39

我有一个事件模型。事件可以有父事件,从模型中的列(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
4

6 回答 6

74

这是一个自引用模型,你可以尝试这样的事情:

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.child_events 来获取事件对象的 ActiveRecord 集合

于 2013-09-13T17:33:45.730 回答
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 文档:http: //api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

具体来说,“自定义查询”部分。这应该允许你做你正在寻找的东西。没有在本地尝试过,但这类似于我前一段时间为实现一个足球pickem应用程序所必须做的。

希望这可以帮助。

于 2013-09-13T17:35:00.507 回答
2

Rails 已经有了提供嵌套树结构祖先的 gem 。在这种情况下最好:

https://github.com/stefankroes/ancestry

您将能够访问以下方法:

event.parent
event.children
event.siblings
于 2013-09-13T17:29:00.267 回答
2

尝试嵌套集模式

对于这个:Awesome Nested Set

于 2013-09-13T17:25:46.390 回答
1

我发现在 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
于 2017-11-18T21:44:02.287 回答
0

我不确定这是 Rails 6 的新功能,但 Rails Guide on Active Record Associations有一个关于自联接的部分,它提供了一个更简洁的解决方案:

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

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

于 2020-08-20T14:13:30.073 回答