跨2个模型的联合查询(has_many)

时间:2015-12-07 21:27:46

标签: ruby-on-rails postgresql activerecord subquery associations

嗨,我需要帮助,所有的见解都值得赞赏。我有两个模型拍卖和投标,我想要检索所有拍卖current_user赢了,他/她已经出价过高和他/她赢得的那些

以下是两种模式:

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)

但可能有更好的方法。

1 个答案:

答案 0 :(得分:0)

您可能无法从控制器访问current_user(设计?)。因此,您需要将用户作为参数传递给类或实例方法。您应该研究的是范围,尤其是接受参数的范围。范围可以真正帮助您重构您的拍卖模型(您实际上不需要任何只返回where())的方法,但也解决了无法访问的current_user。

在拍卖模式中使用它:

scope: :highest_bidder -> (current_user) { where(highest_bidder: current_user) }

从你的控制器那样称呼它:

@auctions = Auction.closed_auctions.highest_bidder(current_user)