【问题标题】:Correct way to permit strong parameters for nested attributes in Rails在 Rails 中允许嵌套属性使用强参数的正确方法
【发布时间】:2017-10-15 09:34:18
【问题描述】:

我的模型名为 note.rb 如下:

class Note < ApplicationRecord
    belongs_to :user
    has_many :tags
    accepts_nested_attributes_for :tags
end

还有一个名为tag.rb的模型:

class Tag < ApplicationRecord
    belongs_to :note
end

新建笔记的形式如下:

<%= form_with scope: :note, url: notes_path, local: true do |f| %>
  <p>
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </p>

  <p>
    <%= f.label :description %><br>
    <%= f.text_area :description %>
  </p>
    <%= f.fields_for :tags_attributes do |t| %>
    <p>
      <%= label_tag(:name, "Add a tag") %><br>
      <%= t.text_field :name %>

    </p>    

    <% end %>

  <p>
    <%= f.submit %>
  </p>
<% end %>
<div id= "tag-displayer">
   <span id= "tags"></span>
</div>

我正在尝试为带有注释记录的标签创建记录。

在我的 notes_controller.rb 我有

def create
    @note = Note.new(note_params) 
    @note.user = current_user
    if @note.save 
      redirect_to '/notes'
    else 
      render 'new' 
    end         
end

和:

private
  def note_params
    params.require(:note).permit(:title, :description, tags_attributes: [:id, :name])
  end

现在在提交表单时,我得到以下信息:

TypeError (no implicit conversion of Symbol into Integer):

如果我使用,我会得到同样的错误:

params.require(:note).permit(:title, :description, :tags_attributes => [:id, :name])

我得到错误:

Unpermitted parameter: :tags_attributes

如果我使用:

params.require(:note).permit(:title, :description, :tags_attributes => [])

表单提交参数:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"iSsLyOb0ZxZP0rfB4I5yfyrw965zJSLrtkroTUzseY2k4o5DwKpKXlyxN6p99pt4Fwju1RhMZPkbNdv+YVSESQ==", "note"=>{"title"=>"test note with Tag", "description"=>"Test note with tag", "tags_attributes"=>{"name"=>"Rails"}}, "commit"=>"Save Note"}

我不确定自己做错了什么,我已经尝试了所有可能的解决方案。

在 ruby​​ 2.4.1 中使用 Rails 5。

【问题讨论】:

    标签: ruby-on-rails ruby nested-attributes strong-parameters


    【解决方案1】:

    好吧,如果我查看您的参数,您实际上确实有字符串。有几种方法可以解决这个问题,但我认为最直接的方法就是允许字符串而不是符号。对于tags_attributes,应该是'tags_attributes' => ...,其余的我不确定我是否记得正确:它是'title'或:'title',可能是后者。我认为'note'或:'note'也是如此。我希望你可以随便玩一下,看看是哪一个。我之前遇到过错误,所以我很确定应该修复它。我希望我能帮上忙!请让我知道哪一个修复了它,我很想知道:)

    【讨论】:

    • 对不起,我不完全确定,我还在学习自己。我希望我能帮上忙
    • 你能给我完整的堆栈跟踪错误消息吗?和行号?
    • Rails 默认使用 HashWithIndifferentAccess 转换参数。因此,所有的字符串键都可以通过它们对应的符号来访问。例如:params[:tag_attributes][:name] 将返回“rails”而不是 nil。因此不需要在强参数中添加字符串而不是符号
    【解决方案2】:

    我认为你不需要在强参数中添加 id

    试试这个:-

    params.require(:note).permit(:title, :description, tags_attributes: [:name])
    

    【讨论】:

      【解决方案3】:

      当前的问题是您的表单正在通过:

      {..., "tags_attributes"=>{"name"=>"Rails"}}, ...}
      

      什么时候需要通过:

      {..., "tags_attributes"=>[{"name"=>"Rails"}], ...}  # The hash is inside an array.
      

      或者可能:

      {..., "tags_attributes"=>{"any_key_except_id" => {"name"=>"Rails"}}, ...} 
      

      我很确定 TypeError 来自该问题,可能在某些时候它试图将字符串 "Rails" 视为哈希并尝试在其上调用 "Rails"[:id]

      我的预感(没有复制你的整个设置)是这可以通过改变你的行来解决:

          <%= f.fields_for :tags_attributes do |t| %>
      

          <%= f.fields_for :tags do |t| %>
      

      如果您查看documentation for fields_for,它使用关联的名称,末尾没有_attributes。对于:tags_attributes,我认为表单不知道如何处理它,假定它是单个项目而不是集合,因此不会将属性嵌套在数组中。

      请注意,如果您想让它显示新标签的字段(而不仅仅是现有标签),我相信您必须在 fields_for 调用之前的某个地方调用 @note.tags.build 以便有一个未保存的 @ tags 集合中的 987654335@ 实体。

      【讨论】:

        【解决方案4】:

        我认为这与您的模型声明 has_many :tags 和您的表单数据作为对象 :tags_attributes =&gt; {id: "", name: ""} 进来有关。

        当您尝试保存注释@note.save 或使用@note = Note.new(note_params) 初始化它时,TypeError (no implicit conversion of Symbol into Integer): 错误可能会冒泡,但不是因为强参数。强参数应该允许这些参数,因为定义与您发送的表单数据相匹配。

        尝试修改前端以数组格式发送标签,如:tags_attributes =&gt; [{id: "", name: ""}, {id: "", name: ""}]

        有一个博客几乎与您所面临的问题相似,请查看http://billpatrianakos.me/blog/2013/09/29/rails-tricky-error-no-implicit-conversion-from-symbol-to-integer/

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-07-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-12
          • 1970-01-01
          相关资源
          最近更新 更多