ruby-on-rails - accepts_nested_attributes_for 是否也应该正确设置关联?

标签 ruby-on-rails ruby nested-attributes

给定某种事物:

class Thing < ApplicationRecord
  include CustomFieldable
  #...
end

它可以附加自定义字段值:

module CustomFieldable
  extend ActiveSupport::Concern

  included do
    has_many :custom_field_values, as: :custom_fieldable, dependent: :destroy
    validates_associated :custom_field_values
    accepts_nested_attributes_for :custom_field_values
  end
end

自定义字段值基本上只是一个字符串值(至少现在是这样)并引用了它们的所有者:

class CustomFieldValue < ApplicationRecord
  belongs_to :custom_fieldable, polymorphic: true, dependent: :destroy
  belongs_to :custom_field, dependent: :destroy

  validates_presence_of :custom_fieldable
  validates_presence_of :custom_field
  validates_presence_of :string_value
end

自定义字段,它只是一个名称的包装器:

class CustomField < ApplicationRecord
  validates_presence_of :name
  validates_uniqueness_of :name
end

当我用散列初始化 Thing 时:

"thing"=>{
  //...other stuff...
  "custom_field_values_attributes"=>{
    "0"=>{
      "custom_field_id"=>"1",
      "string_value"=>"value 1"
    }
  }
}

我希望 ActiveRecord 建立从 CustomFieldValueThing 的关联。但看起来不是,因为我收到验证错误:

There were problems with the following fields:

  • Custom field values custom fieldable can't be blank
  • Custom field values is invalid

所以就像当我使用 accepts_nested_attributes_for 时,没有设置父关联。这是预期的行为吗?

更新#1:

允许字段的 Controller 逻辑如下所示:

class ThingController < ApplicationController

  def thing_params(action)
    common_params = [ omitting common stuff... ]
    params.fetch(:licence).permit(*common_params,
                                  custom_field_values_attributes: [
                                    :custom_field_id, :string_value ])
  end
end

更新#2:

如果我为模型编写两个测试,我可以看到发生同样的事情。

失败:

  test "adding a custom field value on construction via nested attributes" do
    thing = Thing.new custom_field_values_attributes: [
      { custom_field_id: custom_fields(:environment).id,
        string_value: 'Testing' }
    ]
    assert_attribute_not_invalid thing, :custom_field_values
    assert_equal 'Testing', thing.custom_field_values[0].string_value
  end

通行证:

  test "adding a custom field value via nested attributes" do
    thing = things(:one)
    thing.update_attributes custom_field_values_attributes: [
      { custom_field_id: custom_fields(:environment).id,
        string_value: 'Testing' }
    ]
    assert_valid thing
    assert_equal 'Testing', thing.custom_field_values[0].string_value
  end

就像,如果记录还没有保存,Rails 不会正确设置嵌套模型,但如果它已经保存,它们就会正确设置。

最佳答案

我一时兴起尝试了一些东西。改变了这个:

    has_many :custom_field_values, as: :custom_fieldable, dependent: :destroy

对此:

    has_many :custom_field_values, as: :custom_fieldable, inverse_of: :custom_fieldable, dependent: :destroy

所以 Rails 似乎无法猜测多态关联的反向关系 - 尽管我已经被迫使用 :as 告诉它这一点。指定它两次可以正常工作。

关于ruby-on-rails - accepts_nested_attributes_for 是否也应该正确设置关联?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38887701/

相关文章:

ruby - 你如何将一段文字解析成句子? (最好用 Ruby)

ruby - 在 Rails 3 应用程序中调用 .ajax 方法时出现 401 Unauthorized

ruby-on-rails - Bundler::RubyVersionMismatch: 你的 Ruby 版本是 1.9.3,但是你的 Gemfile 指定了 2.0.0

ruby-on-rails - 如何限制用户只能编辑他们的记录

ruby-on-rails - Rails - 多对多过滤

ruby-on-rails - 如何防止 <p> 标签在 Rails 中使用 tinymce 环绕我的输入?

ruby-on-rails - 通过复选框添加多个嵌套属性 Rails 4(可能有多种形式)

MySQL Order by bool 值 tinyint

ruby-on-rails - 验证嵌套属性的数量

ruby-on-rails - Rails - 如何在不使用 Accepts_nested_attributes_for 的情况下管理嵌套属性?