rails model has_many本身

时间:2013-09-13 17:20:06

标签: ruby-on-rails activerecord model has-many

我有一个活动模型。事件可以具有父事件,从模型中的列(parent_event_id)设置。我需要能够在模型上执行has_many :event,所以我可以这样做,例如event.child_eventevent.parent_event。但我的谷歌搜索并没有那么好。

我的模特:

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

我的架构:

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

6 个答案:

答案 0 :(得分:67)

这是一个自我参照模型,您可以尝试这样的事情:

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

这样,您可以调用@ event.parent来获取ActiveRecord Event对象,并调用@ event.child_events来获取Event对象的ActiveRecord集合

答案 1 :(得分:4)

您需要将has_many更改为以下内容:

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

这是来自链接上的rails 4 docs: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

具体来说,有关“自定义查询”的部分。 这应该可以让你做你想要的。没有尝试在本地,但这类似于我必须做的实现我做了一段时间的足球pickem应用程序。

希望这有帮助。

答案 2 :(得分:2)

Rails已经有了一个用于提供嵌套树结构祖先的宝石。在这种情况下最好:

https://github.com/stefankroes/ancestry

您将能够访问以下方法:

event.parent
event.children
event.siblings

答案 3 :(得分:1)

尝试Nested Set Pattern

对于这个:Awesome Nested Set

答案 4 :(得分:0)

我发现在Rails 5中,属于默认情况下已成为强制性的,因此无法保存我的模型实例...在推荐的解决方案的第一行添加可选项修复此问题...

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

答案 5 :(得分:0)

我不确定这对Rails 6来说是新的,但是关于Active Record Associations has a section on self-joins的Rails指南提供了更整洁的解决方案:

class Event < ApplicationRecord
  has_many :children, class_name: "Event", foreign_key: "parent_id"
 
  belongs_to :parent, class_name: "Event", optional: true
end

请注意,只有子事件需要parent_id。从属关系的关联中,可选项是必需的,以允许您保存模型,因为从Rails 5开始,属属关系是必需的。