Rails has_one和accepts_nested_attributes_for

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rails has_one和accepts_nested_attributes_for相关的知识,希望对你有一定的参考价值。

我似乎无法与accepts_nested_attributes_for建立一个has_one关系。这是我第一次涉足嵌套属性,因此可能不正确。救命!

楷模:

class Case < ActiveRecord::Base
  has_one :logged_event, class_name: 'Event', dependent: :destroy
  accepts_nested_attributes_for :logged_event
end

class Event < ActiveRecord::Base
  belongs_to :case
  belongs_to :user
  validates :case, presence: true
  validates :user, presence: true
end

控制器:

class CasesController < ApplicationController
  load_and_authorize_resource

  def new
    @case.build_logged_event(user: current_user)
  end

  def create
    if @case.save
      flash[:notice] = 'Case was successfully logged.'
      redirect_to cases_path
    else
      render 'cases/new'
    end
  end
end

形成:

<h1>New Case</h1>
<%= error_messages_for :case %>
<%= form_for(@case) do |form| %>
  <p>
    <%= form.label(:study) %>:
    <%= form.select(:study, Case.options_for(:study), include_blank: true) %>
  </p>
  <%= form.fields_for(:logged_event) do |logged_event_form| %>
    <%= logged_event_form.label(:created_at, 'Date Case was opened:') %>
    <%= logged_event_form.select(:created_at, [['Today', Date.today], ['Yesterday', Date.yesterday]]) %>
  <% end %>    
  <%= form.submit('Log Case') %> or <%= link_to('cancel', cases_path) %>
<% end %>

它表示记录的事件没有获得用户ID或案例ID,因此事件类的两个验证都失败了。看起来像:

以下字段存在问题: 记录的事件案例不能为空 记录的事件用户不能为空

我不明白,因为在新动作中我已经构建了对象。我也试过form.fields_for(:logged_event, @case.logged_event),但这也没用。

答案

这是因为当你提交表格时没有调用new。只有create行动正在进行。所以@case只填充了提交数据;没有用户或案例分配给它,因为它不在表单中。

在尝试保存(并运行验证)之前,您需要分配usercase@case属性

另一答案

原来你不应该双方验证。我正在验证一个案件有一个事件,一个事件有案件。通过从事件中移除validates :case, presence: true,一切都按预期工作。

另一答案

您不需要删除验证 - 您只需要将inverse_of添加到关联声明中,以告诉Rails为您管理反向引用。

您的模型应如下所示:

class Case < ActiveRecord::Base
  has_one :logged_event, class_name: 'Event', dependent: :destroy, inverse_of: :case
  accepts_nested_attributes_for :logged_event
end

class Event < ActiveRecord::Base
  belongs_to :case, inverse_of: :logged_event
  belongs_to :user, inverse_of: :logged_event # or inverse_of: :event -- you didn't provide your User model
  validates :case, presence: true
  validates :user, presence: true
end

以上是关于Rails has_one和accepts_nested_attributes_for的主要内容,如果未能解决你的问题,请参考以下文章

has_one , belongs_to 和 create_before 在 rails

Rails:在父模型的视图中创建一个 has_one 模型?

Rails - has_one 关系:关联和非关联对象的范围

Rails:在 rails 中使用带有 has_one 关联的 build

Rails has_one和accepts_nested_attributes_for

Rails 中具有相同键的两个表而不是 has_one 关系