Rails有很多条件

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  '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  'Profile', :foreign_key => "(CASE WHEN friendships.profile_id = #{self.id} THEN friend_id ELSE profile_id END)" end 

使用单引号括起条件:

 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 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) 

在关系中使用重型条件必然会带来麻烦。 如果可能的话,尝试对表进行非规范化,创建具有“简单”数据版本的派生列,或者使查询更容易的其他事项。

你真的有两个关系。 你有:

  • 来自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"}) ,但这是一个相当复杂的事情案件。 那种情况非常复杂。