跨 2 个模型的联合查询 (has_many)
Joint query across 2 models (has_many)
您好,我需要帮助,感谢您的所有见解。我有两个模型 Auctions 和 Bids,我想检索所有拍卖 current_user 获胜,那些 s/he 出价过高,那些 s/he 获胜
以下是两个模型:
class Auction < ActiveRecord::Base
extend FriendlyId
friendly_id :guid, use: :slugged
before_save :populate_guid
mount_uploaders :images, ImageUploader
belongs_to :client
has_many :bids, dependent: :destroy
has_one :order, dependent: :destroy
validates_presence_of :title, :lien_price,
:end_time, :collateral_value,
:redemption_date, :current_interest_rate,
:additional_tax, :collateral_details,
:location, :client_id, :starting_bid
validate :end_time_in_the_future, :on => :update
validates_uniqueness_of :guid, case_sensitive: false
def end_time_in_the_future
errors.add(:end_time, "can't be in the past") if self.end_time && self.end_time < Time.now
end
def self.get_active_auctions
where("end_time > ?", Time.now)
end
def self.closed_auctions
where("end_time < ?", Time.now)
end
def highest_bid
self.bids.maximum("amount")
end
def highest_bid_object
self.bids.order(:amount => :desc).limit(1).first
end
def highest_bidder
self.highest_bid_object.user if highest_bid_object
end
def closed?
self.end_time < Time.now
end
private
def populate_guid
if new_record?
while !valid? || self.guid.nil?
self.guid = SecureRandom.random_number(1_000_000_000).to_s(36)
end
end
end
end
和
class Bid < ActiveRecord::Base
extend FriendlyId
friendly_id :guid, use: :slugged
belongs_to :auction
belongs_to :user
before_save :populate_guid
validates_presence_of :amount, :user_id,
:auction_id
#validate :higher_than_current?
validates :amount, :numericality => true
validates_uniqueness_of :guid, case_sensitive: false
def higher_than_current?
if !Bid.where("amount > ? AND auction_id = ?", amount, self.auction.id).empty?
errors.add(:amount, "is too low! It can't be lower than the current bid, sorry.")
end
end
private
def populate_guid
if new_record?
while !valid? || self.guid.nil?
self.guid = SecureRandom.random_number(1_000_000_000).to_s(36)
end
end
end
end
我以为
@auctions = Auction.closed_auctions.where(highest_bidder: current_user)
或
@auctions = Auction.closed_auctions.joins(:bids).where(highest_bidder: current_user)
可以工作,但它们都会引发错误。
编辑此作品
@auctions = Auction.closed_auctions.references(highest_bidder: current_user)
但可能还有更好的方法。
您可能无法从控制器(设计?)访问 current_user。因此,您需要将用户作为参数传递给 class 或实例方法。您应该研究的是作用域,尤其是接受参数的作用域。作用域可以真正帮助你重构你的拍卖模型(你真的不需要任何只有 return 一个 where() 的方法),而且还可以解决无法访问的 current_user。
在您的拍卖模型中像这样使用它:
scope: :highest_bidder -> (current_user) { where(highest_bidder: current_user) }
然后从你的控制器中这样调用它:
@auctions = Auction.closed_auctions.highest_bidder(current_user)
您好,我需要帮助,感谢您的所有见解。我有两个模型 Auctions 和 Bids,我想检索所有拍卖 current_user 获胜,那些 s/he 出价过高,那些 s/he 获胜
以下是两个模型:
class Auction < ActiveRecord::Base
extend FriendlyId
friendly_id :guid, use: :slugged
before_save :populate_guid
mount_uploaders :images, ImageUploader
belongs_to :client
has_many :bids, dependent: :destroy
has_one :order, dependent: :destroy
validates_presence_of :title, :lien_price,
:end_time, :collateral_value,
:redemption_date, :current_interest_rate,
:additional_tax, :collateral_details,
:location, :client_id, :starting_bid
validate :end_time_in_the_future, :on => :update
validates_uniqueness_of :guid, case_sensitive: false
def end_time_in_the_future
errors.add(:end_time, "can't be in the past") if self.end_time && self.end_time < Time.now
end
def self.get_active_auctions
where("end_time > ?", Time.now)
end
def self.closed_auctions
where("end_time < ?", Time.now)
end
def highest_bid
self.bids.maximum("amount")
end
def highest_bid_object
self.bids.order(:amount => :desc).limit(1).first
end
def highest_bidder
self.highest_bid_object.user if highest_bid_object
end
def closed?
self.end_time < Time.now
end
private
def populate_guid
if new_record?
while !valid? || self.guid.nil?
self.guid = SecureRandom.random_number(1_000_000_000).to_s(36)
end
end
end
end
和
class Bid < ActiveRecord::Base
extend FriendlyId
friendly_id :guid, use: :slugged
belongs_to :auction
belongs_to :user
before_save :populate_guid
validates_presence_of :amount, :user_id,
:auction_id
#validate :higher_than_current?
validates :amount, :numericality => true
validates_uniqueness_of :guid, case_sensitive: false
def higher_than_current?
if !Bid.where("amount > ? AND auction_id = ?", amount, self.auction.id).empty?
errors.add(:amount, "is too low! It can't be lower than the current bid, sorry.")
end
end
private
def populate_guid
if new_record?
while !valid? || self.guid.nil?
self.guid = SecureRandom.random_number(1_000_000_000).to_s(36)
end
end
end
end
我以为
@auctions = Auction.closed_auctions.where(highest_bidder: current_user)
或
@auctions = Auction.closed_auctions.joins(:bids).where(highest_bidder: current_user)
可以工作,但它们都会引发错误。
编辑此作品
@auctions = Auction.closed_auctions.references(highest_bidder: current_user)
但可能还有更好的方法。
您可能无法从控制器(设计?)访问 current_user。因此,您需要将用户作为参数传递给 class 或实例方法。您应该研究的是作用域,尤其是接受参数的作用域。作用域可以真正帮助你重构你的拍卖模型(你真的不需要任何只有 return 一个 where() 的方法),而且还可以解决无法访问的 current_user。
在您的拍卖模型中像这样使用它:
scope: :highest_bidder -> (current_user) { where(highest_bidder: current_user) }
然后从你的控制器中这样调用它:
@auctions = Auction.closed_auctions.highest_bidder(current_user)