Rails 管理员:has_one 关联表单已损坏

Ant*_*zée 5 ruby-on-rails rails-admin ruby-on-rails-4

当尝试使用has_one关系(以及所有inverse_of正确指定的)创建新记录时,表单被禁用:

在此处输入图片说明

该关联的代码如下:

class Visit < ActiveRecord::Base
  has_one :mri, dependent: :destroy, inverse_of: :visit

  accepts_nested_attributes_for :mri, update_only: true
  ...
end

class Mri < ActiveRecord::Base
  belongs_to :visit, inverse_of: :mri, touch: true
  ...
end
Run Code Online (Sandbox Code Playgroud)

我用 删除整行时accepts_nested_attributes,我得到一个丢失的表格,什么都没有:

根本没有形式。

使用 rails_admin 配置禁用嵌套表单,如下所示,给出相同的结果。

config.model Visit do
  edit do
    configure :mri do
      nested_form false
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

Ant*_*zée 5

这些问题来自 Rails Admin,IMO 的两个错误。

理解 Rails Admin 有两种关联表单是很有用的。一个是经典的(打开一个窗口进行创建),另一个是在页面中显示表单的“nested_form”。该nested_form参数可以直接更改,如上面的问题所示,但对于包含在accepts_nested_attributes_for.

第一个错误accepts_nested_attributes_for: ..., update_only: true被 rails 管理员“解释”为“我不想在创建时提供参数”。这种解释似乎是错误的,因为update_only在 rails中更改的行为仅涉及对象更新,并且不会阻止在创建时传递嵌套参数。此外,我原以为会退回到经典形式而不是完全禁用的形式。

解决此问题的一种快速且通常有害的方法是更改update_only为默认值false

第二个错误更令人惊讶,因为“在你的脸上”。如wiki 所示,has_one如果您没有为自己指定 id setter 和 getter ,则关系的经典(非嵌套)关联表单将无法正确初始化。因此,如果您没有nested_attributes,则需要在模型中包含这样的行:

class Visit < ActiveRecord::Base
  has_one :mri, dependent: :destroy, inverse_of: :visit

    def mri_id
    self.mri.try :id
  end

  def mri_id=(id)
    self.mri = Mri.find_by_id(id)
  end

  ...
end
Run Code Online (Sandbox Code Playgroud)

最后,利用我们对第一个错误的理解,为我们最初的问题提供了最优雅的解决方案。Rails Admin 模板的源代码显示,Rails Adminupdate_onlynested_form字段对象的属性存储了一个参数。我们可以直接配置它以实现所需的行为(应该是默认的 imo):

config.model Visit do
  edit do
    configure :mri do
      nested_form[:update_only] = false
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

PS:这篇文章很长,但这个简单的问题最终陷入了困境,所以我想分享我的发现 - 我希望它有所帮助。非常感谢 RA 开发人员,他们为 Rails 提供了功能最丰富、功能最丰富的管理门户之一(有史以来)。我已经打开 几个gh 问题。