首页 > 解决方案 > Rails 表单助手:一个表单中的多个嵌套模型,如“Article.comments”?

问题描述

这是form_withRails“入门”指南 ( https://guides.rubyonrails.org/getting_started.html ) 中用于嵌套 Article 模型的视图助手CommentArticle.comments

<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>
 
<p>
  <strong>Text:</strong>
  <%= @article.text %>
</p>
 
<h2>Add a comment:</h2>
<%= form_with(model: [ @article, @article.comments.build ], local: true) do |form| %>
  <p>
    <%= form.label :commenter %><br>
    <%= form.text_field :commenter %>
  </p>
  <p>
    <%= form.label :body %><br>
    <%= form.text_area :body %>
  </p>
  <p>
    <%= form.submit %>
  </p>
<% end %>
 
<%= link_to 'Edit', edit_article_path(@article) %> |
<%= link_to 'Back', articles_path %>

class Article < ApplicationRecord
  has_many :comments
  validates :title, presence: true,
                    length: { minimum: 5 }
end

class Comment < ApplicationRecord
  belongs_to :article
end

现在我想知道是否可以使用form_with助手或其他助手或助手组合来创建或编辑具有多个嵌套模型(如评论、标签等)的新文章......以及文章的进一步模型可能组成。

...它创建了一个理智且有用的参数哈希(因为我自己的带有“fields_for”表单助手的解决方案不会产生所需或有用的参数哈希。

这就是 params-hash 的样子:

<ActionController::Parameters {"utf8"=>"✓&quot;, "_method"=>"patch", "authenticity_token"=>"BeCtYS/U6lugXzzplTEBsMXAiD0x7z28iBUblHiza379p4YqRcd+ykgd49o53oOrC8o+iPhtWnvQQHe0ugCJow==", "article"=>{"parent_article_id"=>"", "title"=>"Überschrift", "text"=>"Toller Text"}, "tags"=>{"name"=>"Rails"}, "commit"=>"Update Article", "controller"=>"articles", "action"=>"update", "id"=>"1"} permitted: false>

问题是控制器/文章 ID 未包含在该:article键下。我不知道如何为 strong_parameters 解决这个问题,我什至不想这样做。我更希望 Rails 只是按照最少惊讶的原则运行,而不是做一些骇人听闻的事情来让事情正常工作。

在这种情况下,我希望是我自己对表单助手的无知和缺乏知识阻止了 Rails 生成正确的 params-hash。

谢谢。

标签: ruby-on-railsstrong-parametersview-helpers

解决方案


Rails 应该按照您的预期执行此操作。来自accepts_nested_attributes

考虑一个有很多帖子的成员:

class Member < ActiveRecord::Base
  has_many :posts
  accepts_nested_attributes_for :posts
end

您现在可以通过成员的属性散列设置或更新关联帖子的属性:将键 :posts_attributes 包含一个帖子属性的散列数组作为值。

对于每个没有 id 键的散列,将实例化一个新记录,除非 > 散列还包含评估为 true 的 _destroy 键。

params = { member: {
  name: 'joe', posts_attributes: [
    { title: 'Kari, the awesome Ruby documentation browser!' },
    { title: 'The egalitarian assumption of the modern citizen' },
    { title: '', _destroy: '1' } # this will be ignored
  ]
}}


member = Member.create(params[:member])
member.posts.length # => 2
member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!'
member.posts.second.title # => 'The egalitarian assumption of the modern citizen'

您显示的参数哈希非常奇怪。看起来您正在手动制作断开连接的字段,parent_article_id而不是实际使用form_withand的功能fields_for

我需要查看您的视图和控制器代码,以了解您是如何实现的form_with,并fields_for帮助您以您想要的方式嵌套这些参数。


推荐阅读