【问题标题】:rails model has_many of itselfrails 模型 has_many 本身
【发布时间】:2013-09-13 17:20:06
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

    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 来获取一个ActiveRecord 的Event 对象集合

    【讨论】:

    • 我们在belongs_tohas_many 中都需要foreign_key 吗?
    • 我们可以使用accepts_nested_attributes_for :child_events, allow_destroy: true吗?
    • 此解决方案将父 ID 设置为“child_event_id”字段。如果我使用“parent_event_id”作为两个关系的外键,它会按预期工作
    【解决方案2】:

    你会想把你的 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

    特别是“自定义查询”部分。 这应该允许你做你正在寻找的东西。没有在本地尝试过,但这与我前段时间实现足球捡球应用程序所必须做的类似。

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      试试Nested Set Pattern

      对于这个:Awesome Nested Set

      【讨论】:

        【解决方案4】:

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

        https://github.com/stefankroes/ancestry

        您将能够访问以下方法:

        event.parent
        event.children
        event.siblings
        

        【讨论】:

          【解决方案5】:

          我发现在 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
          

          【讨论】:

            【解决方案6】:

            我不确定这是 Rails 6 的新功能,但 Rails 活动记录关联指南has a section on self-joins 提供了一个更简洁的解决方案:

            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 是强制性的。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-03-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-05-15
              • 2011-09-27
              相关资源
              最近更新 更多