web-dev-qa-db-fra.com

rails modèle has_many de lui-même

J'ai un modèle d'événement. Les événements peuvent avoir des événements parents, définis à partir d'une colonne du modèle (parent_event_id). Je dois pouvoir faire has_many :event sur le modèle, je peux donc simplement faire, par exemple, event.child_event ou event.parent_event. Mais ma recherche sur Google n'a pas très bien fonctionné.

Mon modele:

class Event < ActiveRecord::Base
    attr_accessible :days_before, :event_name, :event_date, :list_id, :recipient_email, :recipient_name, :parent_event_id, :is_deleted, :user_id

    belongs_to :user
    has_many :event_email
    has_many :event
end

Mon schéma:

create_table "events", :force => true do |t|
    t.datetime "event_date"
    t.integer  "days_before"
    t.string   "recipient_email"
    t.integer  "list_id"
    t.string   "recipient_name"
    t.datetime "created_at",                         :null => false
    t.datetime "updated_at",                         :null => false
    t.integer  "user_id"
    t.string   "event_name"
    t.integer  "parent_event_id"
    t.boolean  "is_deleted",      :default => false
end
31

Ceci est un modèle auto-référentiel, vous pouvez essayer quelque chose comme ceci:

class Event < ActiveRecord::Base
  belongs_to :parent, :class_name => "Event", :foreign_key => "parent_event_id"
  has_many :child_events, :class_name => "Event", :foreign_key => "child_event_id"
end

De cette façon, vous pouvez appeler @ event.parent pour obtenir un objet ActiveRecord Event et @ event.child_events pour obtenir une collection ActiveRecord d'objets Event.

67
derekyau

Vous voudrez changer votre has_many en quelque chose comme ceci:

has_many :parent_events, class_name: 'Event'
has_many :child_events, ->(event) { where parent_event_id: event.id }, class_name: 'Event'

Ceci est tiré de la documentation de Rails 4 au lien: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

Plus précisément, la section "Personnalisation de la requête". Cela devrait vous permettre de faire ce que vous cherchez. Je ne l’ai pas essayé localement, mais c’est similaire à ce que j’avais à faire pour mettre en place une application de football pickem que j’avais faite il ya quelque temps.

J'espère que cela t'aides.

4
Mike Waldrup

Rails a déjà une gemme pour fournir une structure d’arbre imbriquée ascestry . Ce sera mieux dans de tels scénarios:

https://github.com/stefankroes/ancestry

Vous pourrez accéder aux méthodes suivantes:

event.parent
event.children
event.siblings
2
Aman Garg
1
Oleg Haidul

J'ai constaté que dans Rails 5, l'appartenance à est devenue obligatoire par défaut. Je ne pouvais donc pas enregistrer mes instances de modèle. L'ajout facultatif à la première ligne de la solution recommandée corrige ce problème.

class Event < ActiveRecord::Base
  belongs_to :parent, :class_name => "Event", :foreign_key => "parent_event_id", optional: true
  has_many :child_events, :class_name => "Event", :foreign_key => "parent_event_id"
end
0
Phil