Ruby / Rails:has_many关联中的复杂条件

时间:2012-08-08 20:31:17

标签: sql ruby-on-rails ruby ruby-on-rails-3 associations

我有一个Transaction模型。交易有seller_id列和buyer_id。两者都填充了User ID。

所以:

class Transaction
  belongs_to :seller, :class_name => 'User'
  belongs_to :buyer, :class_name => 'User'
end

_

class User
  has_many :selling_transactions, :class_name => 'Transaction', :foreign_key => 'seller_id'
  has_many :buying_transactions, :class_name => 'Transaction', :foreign_key => 'buyer_id'
end

我想要做的是向has_many添加User以关联不完整的交易,无论User是卖方还是买方。

class User
  has_many :incomplete_transactions, :class_name => 'Transaction', :conditions => ???
end

_

我用纯SQL写出来,得到了我想要的结果。我的SQL中的连接是:

left outer join transactions t on ((t.seller_id = users.id and t.buyer_id is NULL) or (t.buyer_id = users.id and t.seller_id is NULL))

如何将join转换为has_many关联?

编辑:
我希望将incomplete_transactions保持为ActiveRecord :: Relation(而不是Array),所以我可以做类似user.incomplete_transactions.limit(15)

的事情。

感谢。

4 个答案:

答案 0 :(得分:1)

pdevisser's的类似答案: 您可以使用类似于此问题的答案:https://stackoverflow.com/a/307724/624590

这基本上会导致:

class User
  has_many :selling_transactions, :class_name => 'Transaction', :foreign_key => 'seller_id'
  has_many :buying_transactions, :class_name => 'Transaction', :foreign_key => 'buyer_id'

  has_many :incomplete_sales, :class_name => 'Transaction', :foreign_key => 'seller_id', :conditions => { :buyer_id => nil }
  has_many :incomplete_purchases, :class_name => 'Transaction', :foreign_key => 'buyer_id', :conditions => { :seller_id => nil }

  def incomplete_transactions
    incomplete_sales + incomplete_purchases
  end
end

编辑:好的,不完全确定如何按照您希望的方式进行设置(使用has_many),但这些内容可能对您有用:

class User
  has_many :selling_transactions, :class_name => 'Transaction', :foreign_key => 'seller_id'
  has_many :buying_transactions, :class_name => 'Transaction', :foreign_key => 'buyer_id'

  def incomplete_transactions
    Transaction.where("(buyer_id = ? and seller_id = NULL) or (seller_id = ? and buyer_id = NULL)", id, id)
  end
end

where语句将返回ActiveRecord::Association,因此您可以在调用时使用limit(或其他activerecord函数)跟随它。

答案 1 :(得分:0)

假设您使用的是rails 3.2,我建议您创建命名范围

class Transaction
  belongs_to :seller, :class_name => 'User'
  belongs_to :buyer, :class_name => 'User'

  scope :incomplete_sales, :conditions => { :buyer_id => nil }
  scope :incomplete_purchases, :conditions => { :seller_id => nil }
end

然后你可以访问不完整的,

user.selling_transactions.incomplete_sales
user.buying_transactions.incomplete_purchases

编辑 - 也纠正了上面的关联

如果您想限制,您可以随时使用数组

执行以下操作
user.selling_transactions.incomplete_sales[0,15]

答案 2 :(得分:0)

修正了它!

这与@ DRobinson的解决方案非常相似,但使用了proc和has_many定义 而不是定义本地方法。

根据3.1发行说明,您现在可以在条件中使用proc!

在proc中,self是作为关联所有者的对象,除非你渴望加载关联,在这种情况下self是关联所在的类。

class User < ActiveRecord::Base
  has_many :incomplete_transactions , :class_name => 'Transaction', 
    :conditions => proc { incomplete_sales + incomplete_purchases }

  has_many :incomplete_sales, :class_name => 'Transaction', :foreign_key => 'seller_id', :conditions => { :buyer_id => nil }
  has_many :incomplete_purchases, :class_name => 'Transaction', :foreign_key => 'buyer_id', :conditions => { :seller_id => nil }

  has_many :selling_transactions, :class_name => 'Transaction', :foreign_key => 'seller_id'
  has_many :buying_transactions, :class_name => 'Transaction', :foreign_key => 'buyer_id'
end

class Transaction < ActiveRecord::Base
  belongs_to :seller, :class_name => 'User'
  belongs_to :buyer, :class_name => 'User'

# scope :incomplete_sales , :conditions => {:buyer_id => nil}
# scope :incomplete_purchases , :conditions => {:seller_id => nil}
end

见:

答案 3 :(得分:0)

您可以使用下面的选项

:conditions = ["(t.seller_id = #{self.id} and t.buyer_id is NULL) or (t.buyer_id = #{self.id} and t.seller_id is NULL)"]
相关问题