0

je les modèles suivants, avec leurs associations concernées:Rails - Besoin d'aide mise en place des associations faiblement couplés

class User < ActiveRecord::Base 
    has_many :reviews 
    has_many :ratings 
end 

class Product < ActiveRecord::Base 
    has_many :reviews 
    has_many :ratings 
end 

class Review < ActiveRecord::Base 
    belongs_to :product 
    belongs_to :user 
end 

class Rating < ActiveRecord::Base 
    belongs_to :product 
    belongs_to :user 
end 

Compte tenu d'un Rating spécifique, je dois aller à la Review correspondante (si un examen existe). Je dois garder ratings et reviews couplé de manière lâche. (Je ne veux pas mettre en place mon modèle afin qu'un Reviewbelongs_to un Rating)

Comment dois-je mettre en place une association rating's-reviews?

Une fois que je travaille avec une note spécifique dans une vue, je peux appeler le @rating.product.reviews.where(:user_id => @rating.user.id).first, mais je voudrais qu'il soit plus propre/plus efficace si possible.

Des idées?

Merci.

Répondre

2

Essayez d'utiliser: conditions comme ceci:

class Rating < ActiveRecord::Base 
    has_many :reviews, 
      :through => :user, 
      :source => :reviews, 
      :conditions => ['#{Review.table_name}.product_id = #{product_id}'] 
end 

Si cela ne fonctionne pas, le faire au lieu (très semblable à ce @RobinBrouwer répondre):

class Rating < ActiveRecord::Base 
    def reviews 
    user.reviews.where(:product => product) 
    end 
end 
+1

Il n'a pas besoin de spécifier deux fois l'utilisateur - 'user.reviews.where (: product => product)' suffira. –

+0

Yep merci, laissé celui accidentellement, fixe. – jimworm

+0

Pouvez-vous expliquer ce qui se passe ici: "{: product_id => &: product_id}"? THX. – johnnycakes

0

Vous pouvez créer un has_many :through relation pour obtenir tous les commentaires.

class Rating < ActiveRecord::Base 
    belongs_to :product 
    belongs_to :user 
    has_many :product_reviews, :through => :product, :source => :reviews 
end 

Vous pouvez maintenant faire ce qui suit pour faire la même chose que vous avez fait ci-dessus:

@rating.product_reviews.where(:user_id => @rating.user.id).first 

Pas vraiment une grande amélioration. Vous pouvez le mettre dans une méthode d'instance pour nettoyer les choses:

def review 
    product_reviews.where(:user_id => user_id).first 
end 

Maintenant, vous pouvez simplement faire ce qui suit pour obtenir le même résultat:

@rating.review 

Voilà.