所以我有两个相关的模型用户和杂志。它们通过订阅与has_many:through关系相关联。所以这就是它的样子:
class User < ActiveRecord::Base
has_many :subscriptions
has_many :magazines, :through => :subscriptions
end
class Subscription < ActiveRecord::Base
belongs_to :user
belongs_to :magazine
end
class Magazine < ActiveRecord::Base
has_many :subscriptions
has_many :users, :through => :subscriptions
end
用户有一个名为paid
的布尔属性。我只希望paid == true
的用户能够订阅任何杂志。如何设置这样的条件关联?在此先感谢您的帮助!
答案 0 :(得分:2)
对于关联,您可以在哈希选项之前传递lambda。在这个lambda中,您可以指定条件,排序等。
class Magazine < ActiveRecord::Base
has_many :subscriptions
has_many :users, ->{ where(users: {paid: true}) }, through: :subscriptions
end
对于用户,您可以这样做:
class User < ActiveRecord::Base
has_many :subscriptions
has_many :magazines, through: :subscriptions
def magazines
self.paid ? super : Magazine.none
end
end
虽然它很整洁,但当您加入表格时,上述情况可能会出现不可预测的情况,例如: User.joins(:magazines)
可能会忽略paid
条件或崩溃。
更好的选择:
class User < ActiveRecord::Base
has_many :subscriptions
has_many :magazines,
->{ where("subscriptions.user_id IN (
SELECT id FROM users WHERE users.paid = 't')") },
through: :subscriptions
end
lambda中的where
可以由joins
替换,如下所示:
joins(subscriptions: :user).where(users: {paid: true})
但我认为'加入subscriptions
两次 - 一次是lambda,一次是关联。我不确定。如果是这样,如果这困扰你,那么:
joins("INNER JOIN users ON (users.id = subscriptions.user_id)").
where(users: {paid: true})
或:
joins("INNER JOIN users ON (
(users.id = subscriptions.user_id) AND (users.paid = 't')
)")
此外,我认为您将Subscription
模型标记为Registration