72 votes

Rails has_many :par le biais de recherche par Attributs Supplémentaires dans la Jointure Modèle

Nouveau à Ruby et Rails, mais je suis livre instruits (qui, apparemment, ne veut rien dire, haha).

J'en ai deux modèles, l'Événement et l'Utilisateur rejoint par le biais d'un tableau EventUser

class User < ActiveRecord::Base
  has_many :event_users
  has_many :events, :through => :event_users
end

class EventUser < ActiveRecord::Base
  belongs_to :event
  belongs_to :user

  #For clarity's sake, EventUser also has a boolean column "active", among others
end

class Event < ActiveRecord::Base
  has_many :event_users
  has_many :users, :through => :event_users
end

Ce projet est un calendrier, dans lequel je dois garder la trace de gens de la signature et de rayer leur nom pour un événement donné. Je me figure la nombreux de nombreux est une bonne approche, mais je ne peux pas faire quelque chose comme ceci:

u = User.find :first
active_events = u.events.find_by_active(true)

Parce que les événements n'ONT pas réellement de données supplémentaires, le EventUser modèle ne. Et alors que je pourrais faire:

u = User.find :first
active_events = []
u.event_users.find_by_active(true).do |eu|
  active_events << eu.event
end

Cela semble être contraire à "les rails de chemin". Quelqu'un peut m'éclairer, ce qui a été m'énerve pour un long temps ce soir (ce matin)?

Merci beaucoup!

124voto

Milan Novota Points 10892

Que diriez-vous quelque chose comme ceci dans votre modèle d'Utilisateur?

has_many  :active_events, :through => :event_users, 
          :class_name => "Event", 
          :source => :event, 
          :conditions => ['event_users.active = ?',true]

Après cela, vous devriez être en mesure d'obtenir événements actifs pour un utilisateur simplement en appelant le:

User.first.active_events

23voto

msanteler Points 422

Milan Novota a une bonne solution, mais :conditions est maintenant obsolète et l' :conditions => ['event_users.active = ?',true] peu juste ne semble pas très rails de toute façon. Je préfère quelque chose comme ceci:

has_many :event_users
has_many :active_event_users, -> { where active: true }, class_name: 'EventUser'
has_many :active_events, :through => :active_event_users, class_name: 'Event', :source => :event

Après cela, vous devriez toujours être en mesure d'obtenir événements actifs pour un utilisateur simplement en appelant le:

User.first.active_events

12voto

Gareth Points 42402

Même si votre u.les événements n'est pas explicitement l'appel de la user_events table, la table est toujours inclus dans le SQL implicitement raison de les jointures nécessaires. Donc, vous pouvez toujours utiliser cette table dans votre conditions de la recherche:

u.events.find(:all, :conditions => ["user_events.active = ?", true])

Bien sûr, si vous prévoyez de faire cette recherche beaucoup, alors assurez-vous, donnez-lui une association indépendante de Milan Novota suggère, mais il n'y a aucune exigence pour vous de le faire de cette façon

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X