有许多通过与条件的关联
我试图通过关联添加一个条件,没有运气。 这是我的video模型中的关联:
has_many :voted_users, :through => :video_votes, :source => :user
我想只获得其video_votes对于该video的value
等于1的voted_users。 我该怎么办?
我建议在video模型类中创建一个模型方法,例如:
def users_with_one_vote self.voted_users, :conditions => ['value = ?', 1] end
然后在控制器中使用video.users_with_one_vote
然后测试也更容易。
您有可能从“值”更改该列名称。 可能会提出一些问题(保留?)。
我分2个阶段做到这一点:
首先,我在没有任何条件的情况下定义了模型之间的has_many :through
关系。
其次,我添加了一个定义where条件的“范围”。
具体来说,我会做类似的事情:
class User < ActiveRecord::Base has_many :video_votes has_many :votes, :through=>:video_votes def self.voted_users self.video_votes.voted end end class VideoVote def self.voted where("value = ?", 1) end end class Video has_many :video_votes has_many :users, :through=>:video_votes end
然后你可以得到投票使用的用户:
VideoVote.voted.collect(&:user).uniq
我认为这将返回所有投票的用户数组。 这不是您使用的确切代码 – 它们只是片段 – 但这个想法是一样的。
将
has_many :voted_users, :through => :video_votes, :source => :user, :conditions => ['users.votes = ?', 1]
诀窍呢?
我发现在我的模型中定义这个方法有效:
def upvoted_users self.voted_users.where("value = 1") end
然后调用@video.upvoted_users
就可以了。
在不弄乱关系的情况下执行此操作的最佳方法是制作更复杂的查询。 对于这个特定问题,关系不是最好的选择。 请理解,关系更像是一种“数据定义方式”,然后是“商业规则定义”的一种方式。
必须在更具体的层上定义业务逻辑或业务规则。
我对您的问题的建议是创建一种方法来搜索仅在您的video上投票一次的用户。 就像是:
class Video < ActiveRecord::Base def voted_once() User.joins(:video_votes).where("video_votes.value == 1 AND video_votes.video_id == ?", this.id) end
Rails对于许多事情都是神奇的,但复杂的查询仍然需要以“SQL”的思维方式完成。 不要让虚幻的面向对象隐喻让你失明
只要我们抛出想法,如何使用关联扩展。
class VideoVote scope :upvotes, where(:value => 1) end class Video has_many :voted_users, :through => :video_votes, :source => :user do def upvoted scoped & VideoVote.upvotes end end end
然后你对完全没有参数进行调用感觉很好而且你在技术上没有为你的video模型添加另一种方法(它在关联上,对吗?)
@video.voted_users.upvoted