c = "(f.profile_id = #{self.id} OR f.friend_id = #{self.id})"
c += AND + "(CASE WHEN f.profile_id=#{self.id} THEN f.friend_id ELSE f.profile_id END = p.id)"
c += AND + "(CASE WHEN f.profile_id=#{self.id} THEN f.profile_rejected ELSE f.friend_rejected END = 1)"
c += AND + "(p.banned = 0)"
我需要将它用于像这样的has_many关系:
has_many :removed_friends, :conditions => ???
我如何在那里设置self.id?或者我如何在那里传递id? 然后我想使用will_paginate插件:
@profile.removed_friends.paginate(:page => 1, :per_page => 20)
感谢您的帮助
编辑:
class Profile < ActiveRecord::Base
has_many :friendships
has_many :removed_friends, :class_name => 'Profile', :through => :friendships, :conditions =>
"(friendships.profile_id = #{self.id} OR friendships.friend_id = #{self.id})"
"AND (CASE WHEN friendships.profile_id=#{self.id} THEN friendships.profile_rejected ELSE friendships.friend_rejected END = 1)" +
"AND (p.banned = 0)"
end
class Friendship < ActiveRecord::Base
belongs_to :profile
belongs_to :removed_friend, :class_name => 'Profile', :foreign_key => "(CASE WHEN friendships.profile_id = #{self.id} THEN friend_id ELSE profile_id END)"
end
答案 0 :(得分:3)
使用单引号括起条件:
class Profile < ActiveRecord::Base
has_many :friendships
has_many :removed_friends, :class_name => 'Profile', :through => :friendships,
:conditions => '
( friendships.profile_id = #{self.id} OR
friendships.friend_id = #{self.id}
) AND
(CASE WHEN friendships.profile_id=#{self.id}
THEN friendships.profile_rejected
ELSE friendships.friend_rejected
END = 1
) AND
(p.banned = 0)'
end
答案 1 :(得分:1)
您可能希望将其分解为一系列可以分阶段应用而不是一次性应用的命名范围。例如,提取被禁止的部分:
class Friend < ActiveRecord::Base
named_scope :banned, lambda { |*banned| {
:conditions => { :banned => banned.empty? ? 1 : (banned.first ? 1 : 0) }
}}
end
@profile.friends.removed.banned(false).paginate(:page => 1, :per_page => 20)
在关系中使用重型条件必然会带来麻烦。如果可能的话,尝试对表进行非规范化,创建具有“简单”版本数据的派生列,或者使其更容易查询的其他内容。
答案 2 :(得分:0)
你这里真的有两个关系。你有:
profile_id
方的被拒绝的友情friend_id
方的被拒绝的友情我不知道为什么双方都可以拒绝友谊,也许你需要在这里稍微看一下你的模型(哪一方要求它?考虑请求者取消请求而不是更好说它被profile
方面拒绝了?)
无论如何,我会把它建模为两个独立的关系:
class Profile
has_many :rejected_friendships, :conditions => 'friendships.profile_rejected = 1'
has_many :canceled_friendships, :foreign_key => 'friend_id', :conditions => 'friendships.friend_rejected = 1'
named_scope :banned, lambda do |*banned|
{ :conditions => {:banned => banned.empty? ? 1 : (banned.first ? 1 : 0) } }
end
has_many :rejected_friends, :class_name => 'Profile', :through => :rejected_friendships
has_many :canceled_friends, :class_name => 'Profile', :through => :canceled_friendships
def removed_friends
(self.rejected_friends.banned(false).all + self.canceled_friends.banned(false).all).uniq
end
end
这有点不受欢迎,因为removed_friends不再是一种关系了,所以你不能再做Profile.removed_friends.find(:all, :conditions => {:name => "bleh"})
这样的事了,但这是一个非常复杂的案例。那种情况非常复杂。