我有一个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)
感谢。
答案 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)"]