使用has_many:through关系创建模型实例的正确方法

时间:2016-02-18 20:50:47

标签: ruby-on-rails ruby activerecord rails-activerecord model-associations

我有以下两个类,我很难找到有关如何正确创建事件和注册用户的信息。任何帮助将不胜感激 - 我的代码在下面

class UserEvents < ActiveRecord::Base
    belongs_to :user
    belongs_to :event
end

class User < ActiveRecord::Base
  has_many :user_events
  has_many :events, :through => :user_events
end

class Event < ActiveRecord::Base
  has_many :user_events
  has_many :attendees, :class_name => "User", :through :user_events
end

用于创建活动的控制器操作

def create
    new_event = event.new(event_params)
    current_user.events << new_event
    new_event.attendees << current_user
    if new_event.save and current_user.save
        render json: new_event, status: :ok
    else
        render json: { errors: "Creation failed" }, status: :unprocessable_entity
end

我是否正确地解决了这个问题?我应该使用一系列ID来跟踪与会者吗?我也看到过类似的方式:

current_user.events.create ( ... )

我不确定采用哪种方法

1 个答案:

答案 0 :(得分:1)

您可以将事件设置为接受嵌套属性,然后使用单个保存创建所有必需对象。这是一个例子:

class Event < ActiveRecord::Base
  has_many :user_events
  has_many :attendees, :class_name => "User", through: :user_outings

  accepts_nested_attributes_for :user_events, allow_destroy: true
end

然后修改控制器中的event_params以接受user_events的属性。例如:

def event_params
  params.permit([
    :..event attributes...,
    user_events_attributes: [...user event attributes here...]
  ])
end

如果它只是当前用户参加新活动,那么这就太过分了。但是,如果您在活动创建时将其他用户添加到活动中,那么您就是这样做的。

如果它只是当前用户,那么您可以修改您的创建操作,如下所示:

def create
    new_event = event.new(event_params)
    new_event.attendees << current_user

    if new_event.save and current_user.save
        render json: new_event, status: :ok
    else
        render json: { errors: "Creation failed" }, status: :unprocessable_entity
end

编辑:您也可以执行accepts_nested_attributes并使用与会者,但您可能需要在模型中使用inverse_of选项。有关详细信息,请参阅https://robots.thoughtbot.com/accepts-nested-attributes-for-with-has-many-through