繁体   English   中英

Rails 5 HABTM 不允许的参数

[英]Rails 5 HABTM Unpermitted parameters

在一天无处可去之后,我认输了(答案可能非常简单,但这就是代码)。

好的,我有 2 个模型,用户(带有设计)和章节。

楷模:

class User < ApplicationRecord
  has_many :projects
  has_and_belongs_to_many :chapters
end

class Chapter < ApplicationRecord
  belongs_to :country
  has_and_belongs_to_many :users
  accepts_nested_attributes_for :users
end

_form.html.erb

[...]
<% @chapter.users.each_with_index do |chap_user, i| %>
  <div class="row">
    <div class="col-md-4 col-md-offset-4  col-xs-8 col-xs-offset-2">
      <small>User <%= i + 1 %></small>
    </div>
  </div>

  <div class="row">
    <div class="col-md-2 col-md-offset-4  col-xs-8 col-xs-offset-2">

      <div class="field form-group">
        <%= form.label 'First Name' %>
        <%= form.text_field :first_name, value: chap_user.first_name,class:"form-control"%>
      </div>
    </div>
    <div class="col-md-2 col-md-offset-0 col-xs-8 col-xs-offset-2">
      <div class="field form-group">
        <%= form.label 'Last Name' %>
        <%= form.text_field :last_name, value: chap_user.last_name, class:"form-control"%>
      </div>

    </div>
  </div>
  <div class="row">
    <div class="col-md-4 col-md-offset-4 col-xs-8 col-xs-offset-2">
      <div class="field form-group">
        <%= form.label :email %>
        <%= form.text_field :email, value: chap_user.email, class:"form-control"%>
      </div>

    </div>
  </div>
<% end %>
[...]

ChaptersController(参数)

private # 使用回调来共享操作之间的通用设置或约束。 def set_chapter @chapter = Chapter.find(params[:id]) end

# Never trust parameters from the scary internet, only allow the white list through.
def chapter_params
  params.fetch(:chapter, {})
  params.require(:chapter).permit(:city, :country_id, user_attributes: [:first_name,:last_name,:email])
end
# or...
params.require(:chapter).permit(:city, :country_id, user_ids: [])
# or...
params.require(:chapter).permit(:city, :country_id, user_attributes: [:id, :first_name])
# or...
params.require(:chapter).permit(:city, :country_id, users_attributes: [:id, :first_name])

控制器中的 binding.pry

  # PATCH/PUT /chapters/1
  # PATCH/PUT /chapters/1.json
  def update
    binding.pry
    respond_to do |format|
      if @chapter.update(chapter_params)
        format.html { redirect_to @chapter, notice: 'Chapter was successfully updated.' }
        format.json { render :show, status: :ok, location: @chapter }
      else
        format.html { render :edit }
        format.json { render json: @chapter.errors, status: :unprocessable_entity }
      end
    end
  end

binding.pry 响应

我知道这个有点难看,但基本上是提交了参数,但不允许 users[:first_name,:last_name,:email]

[1] pry(#)>chapter_params 不允许的参数: :first_name, :last_name, :email => "London", "country_id"=>"1"} 允许: true> [2] pry(#)> params => "✓", "_method"=>"patch", "authenticity_token"=>"9IdAqcAsVG5vvakSf7jHRk+WplN/GyVZUxmAdefUbTX/uI6IajmZPr1YSol21Zhzdl7P/lrl+SVnWr5m",="="="=", SVnWr5m","="="jhzdlwr5m","="jhpL" ", "first_name"=>"Tim2", "last_name"=>"Heard", "email"=>"jmcgregorx@spartaglobal.com"} 允许: false>, "commit"=>"Update", "controller" =>“章节”、“动作”=>“更新”、“id”=>“1”} 允许:false>

简而言之,我想通过表单将某些用户连接到某些章节,但我不知道如何通过章节更新/创建方法获取嵌套参数。 我的头是一团红色,一团糟。 请帮忙。

由于您尝试修改的字段用于子模型,因此您必须告诉表单,因为它假定您在默认情况下正在编辑父模型上的字段。 方法是使用#fields_for (特别是“一对多”部分)。

所以你会按照这些方式做一些事情(代码下面的解释):

<% @chapter.users.each_with_index do |chap_user, i| %>
  <%= form.fields_for :users, chap_user do |user_fields| %>
    <div class="row">
      <div class="col-md-4 col-md-offset-4  col-xs-8 col-xs-offset-2">
        <small>User <%= i+ 1 %></small>
      </div>
    </div>

    <div class="row">
      <div class="col-md-2 col-md-offset-4  col-xs-8 col-xs-offset-2">
        <div class="field form-group">
          <%= user_fields.label 'First Name' %>
          <%= user_fields.text_field :first_name, value: chap_user.first_name,class:"form-control"%>
        </div>
      </div>
      <div class="col-md-2 col-md-offset-0 col-xs-8 col-xs-offset-2">
        <div class="field form-group">
          <%= user_fields.label 'Last Name' %>
          <%= user_fields.text_field :last_name, value: chap_user.last_name, class:"form-control"%>
        </div>
      </div>
    </div>

    <div class="row">
      <div class="col-md-4 col-md-offset-4 col-xs-8 col-xs-offset-2">
        <div class="field form-group">
          <%= user_fields.label :email %>
          <%= user_fields.text_field :email, value: chap_user.email, class:"form-control"%>
        </div>
      </div>
    </div>
  <% end %>
<% end %>

改变的是我使用#fields_for方法将所有表单输入包装在一个块中,以指定现在我们正在修改子属性。 当我们这样做时,我们还指定了一个变量名称,该名称将用于为子模型的属性生成字段。 我将它命名为user_fields ,然后在该块中用user_fields替换了所有form user_fields

在您的 ChaptersController 中,您希望接受参数的行是:

params.require(:chapter).permit(:city, :country_id, users_attributes: [:id, :first_name, :last_name, :email])

您需要users_attributes而不是user_attribute因为复数“users”告诉 rails 期望多个孩子(多个用户)的属性。 然后在该数组中,您想告诉它所有期望的字段,包括id 即使您没有为 ID 显式定义一个字段,Rails 也会放置一个字段来允许您编辑已经存在的子项的属性(并且不仅能够创建新的子项)。 来自文档的片段:

请注意,#fields_for 会自动生成一个隐藏字段来存储记录的 ID。 在某些情况下不需要此隐藏字段,您可以传递 include_id: false 以防止 #fields_for 自动呈现它。

如果关于此的某些内容不起作用,或者您有更多问题,请随时告诉我!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM