多个有许多相同的模型

Multiple has many to the same Model

我有一个带有嵌套模型参加者的模型事件。每个与会者可以是 3 个角色中的一个(:guide、:marshal 和:organizer)。

class Event < ApplicationRecord

  has_many :attendees, dependent: :destroy
  has_many :guides, -> { Attendee.guide }
  has_many :marshals, -> { Attendee.marshal }
  has_many :organizers, -> { Attendee.organizer }
end

_

class Attendee < ApplicationRecord

  belongs_to :event

  validates :name, presence: true
  validates :role, presence: true
  validates :email, email: true

  enum role: %i[guide marshal organizer]

  scope :guide, -> { where(role: :guide) }
  scope :marshal, -> { where(role: :marshal) }
  scope :organizer, -> { where(role: :organizer) }
end

我希望我的活动登记表具有针对每种角色类型的嵌套表单。我正在尝试这样的事情。

<%= form_for @event, url: event_create_path(@event.handle) do |f| %>

    <%= f.fields_for :organizers do |f| %>
        <%= render partial: "attendee_fields", locals: {f: f} %>
    <% end %>

    <%= f.fields_for :guides do |f| %>
        <%= render partial: "attendee_fields", locals: {f: f} %>
    <% end %>

    <%= f.fields_for :marshals do |f| %>
        <%= render partial: "attendee_fields", locals: {f: f} %>
    <% end %>
<% end %>

提交时我收到以下错误。

uninitialized constant Event::Guide

关于如何解决这个问题有什么想法吗?

您的事件模型需要更像这样:

class Event < ApplicationRecord
  has_many :attendees, dependent: :destroy
  has_many :guides, -> { guide }, class_name: "Attendee"
  has_many :marshals, -> { marshal }, class_name: "Attendee"
  has_many :organizers, -> { organizer }, class_name: "Attendee"
end

额外的关联需要知道他们正在链接哪个模型——正如错误所示,他们目前正在猜测,例如guides 与一些名为 Guide 的模型相关联。

(你也不应该在 Attendee 中需要那些 scope,我不认为......我相信 enum 会自动为你定义相同的。)

我仍然会走完全不同的道路来创建更好的领域模型:

class Attendee
  has_many :attendences
  has_many :events, through: :attendences
end

class Attendance
  enum role: %i[guide marshal organizer]
  belongs_to :attendee
  belongs_to :event
end

class Event
  has_many :attendences
  has_many :attendees, through: :attendences

  Attendance.roles.each do |key,int|
    has_many key, through: :attendences,
                  source: :attendee,
                  -> { where(Attendance.call(key)) }
  end
end

您为它建模的方式将与会者锁定为一个角色。这反而会创建作用域为事件的角色。