2010-03-30 8 views
1
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)" 

Je en ai besoin à utiliser dans une relation has_many comme ceci:Rails conditions has_many

has_many :removed_friends, :conditions => ??? 

comment puis-je y mettre le self.id ?, ou comment passer je n'y l'id? Ensuite, je veux utiliser le plugin will_paginate:

@profile.removed_friends.paginate(:page => 1, :per_page => 20) 

Merci pour votre aide

EDIT:

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 

Répondre

3

Utilisez des guillemets simples pour encadrer la condition:

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 
+0

comme ça ça ne marche vraiment pas: s –

+0

Vous devez utiliser des guillemets simples pour que cela fonctionne. Je l'utilise tout le temps. –

+0

J'ai mis à jour ma réponse. Dites-moi si cela marche pour vous. –

1

Vous pourrait vouloir décomposer en une série d'étendues nommées qui peuvent être app menti par étapes au lieu de tout à la fois. À titre d'exemple, extrayez la partie interdite:

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) 

L'utilisation de conditions difficiles dans les relations est susceptible de causer des problèmes. Si possible, essayez de dénormaliser la table, en créant des colonnes dérivées qui ont des versions «faciles» des données, ou d'autres choses pour faciliter l'interrogation.

+0

n'est pas le banni qui est le problème. Je vais vous montrer ce que j'essaie de faire. Je vais éditer ma question précédente .. –

0

Vous avez vraiment deux relations ici. Vous avez:

  • A rejeté l'amitié du côté profile_id
  • A rejeté l'amitié du côté friend_id

Je ne sais pas pourquoi les deux parties peuvent rejeter une amitié, et peut-être que vous devez regardez votre modèle un peu ici (quel côté le demande? Serait-il préférable de considérer que le demandeur a ANNULÉ la demande au lieu de dire qu'il a été rejeté du côté profile?)

En tout cas, je modélise ce que les deux relations distinctes qu'ils sont:

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 

Ceci est un peu indésirable car removed_friends est pas une relation plus que vous ne pouvez pas faire des choses comme Profile.removed_friends.find(:all, :conditions => {:name => "bleh"}) plus, mais c'est un cas assez compliqué. Cette condition est assez complexe.

+0

dans mon DB est comme ceci: profile_id, est celui qui fait la demande, friend_id, est celui qui recive la demande d'ami, alors il y a un profile_rejected qui est initialement faux, mais si le profile_id rejeter l'amitié sera mis à vrai. alors est un friend_rejected qui est faux. alors est un col accepté qui est faux, et après que le friend_id accepte l'amitié sera vraie. l'union ... + ... est vraiment mauvais parce que je ne peux pas faire la demande avec le tri, la limite et l'offset pour bien fonctionner. merci quand même pour votre temps, bientôt je vais vous expliquer mieux ce que je veux dire. je reviens très vite ... –