为什么我的 rails 更新方法使用与我的创建方法相同的强参数,给我一个参数错误?
Why does my rails update method using the same strong params as my create method, give me an argument error?
我正在使用 Rails 5.2 并构建一个 ecomm 站点。
我的 new.html.erb
页面有一个 simple_form,其中包含 Product
字段以及在强参数和新实例创建之外处理的其他参数。
表单的一个功能是 eventListener
,它根据四个输入值自动创建 :sku
。隐藏产品编号、sku 和实时状态。
这里是html.erb
的简化版本:
<%= simple_form_for @new_product do |f| %>
<%= f.error_notification %>
<%= f.input :name%>
<%= f.association :size, collection: @all_sizes.map{ |s| [s.name, s.id, {'data-code-num' => s.code_num}]}, input_html:{class: 'sku-suffix-component'} %>
<%= f.association :color, collection: @all_colors.map{ |s| [s.name, s.id, {'data-code-num' => s.code_num}]}, input_html:{class: 'sku-suffix-component'} %>
<%= f.association :pattern, collection: @all_patterns.map{ |s| [s.name, s.id, {'data-code-num' => s.code_num}]}, input_html:{class: 'sku-suffix-component'} %>
<%= f.input :product_number, as: :hidden, input_html:{ value: @new_product.product_number, class: "sku-suffix-component" } %>
<%= f.input :sku,as: :hidden, html:{id: "new-product-form-sku-input"} %>
<%= f.input :live_status, as: :hidden, :input_html => { :value => @new_product.live_status } %>
<%= f.input :description, as: :text %>
<%= f.association :brand%>
<%= f.association :style %>
<%= f.input :price %>
<%= f.input :quantity, input_html:{value: 1}%>
<%= f.association :segment %>
<%= f.association :main_category %>
<%= f.association :category %>
<%= f.association :country, class: '' %>
<!-- Here are some inputs for adding records to a material join table -->
<!-- And the names of the inputs are dynamically created -->
<% 5.times.with_index do |_, i| %>
<% num = i + 1 %>
<label class="form-control-label integer" for="material_percent_id_<%= num < 10 ? "0" + num.to_s : num.to_s %>">Percent</label>
<input class="form-control numeric integer required" type="number" step="1" name="material_percent_<%= num < 10 ? "0" + num.to_s : num.to_s %>" id="material_percent_id_<%= num < 10 ? "0" + num.to_s : num.to_s %>">
<label class="form-control-label select" for="material_id_id_<%= num < 10 ? "0" + num.to_s : num.to_s %>">Material Component #<%= num %> </label>
<select class="form-control select" name="material_id_<%= num < 10 ? "0" + num.to_s : num.to_s %>" id="material_id_id_<%= num < 10 ? "0" + num.to_s : num.to_s %>">
<option value=""></option>
<% @all_materials.each do |material| %>
<option value="<%= material.id %>"><%= material.name %></option>
<% end %>
</select>
<% end %>
<!-- Here are some inputs for adding multiple photos to the products using active_storage -->
<% (1..8).each do |i| %>
<%= f.label "Photo [#{i}]" %>
<%= f.file_field :photos, multiple: true %>
<% end %>
<%= f.button :submit %>
<% end %>
使用此 simple_form
创建新产品以及连接 table 中的实例通过 create method
工作正常,如下所示:
def create
@all_sizes = Size.all
@all_colors = Color.all
@all_patterns = Pattern.all
@new_product = Product.new(product_params)
@all_materials = Material.all
if @new_product.save
5.times.with_index do |_, i|
if params["material_id_0#{(i + 1)}"] != ""
ProductMaterial.create!(product_id: @new_product.id,
material_id: params["material_id_0#{(i + 1)}"].to_i,
percent: params["material_percent_0#{(i + 1)}"].to_i)
else
break
end
end
redirect_to @new_product
else
render :new
end
end
使用几乎完全相同的形式(添加了一些代码以动态呈现连接 table 输入和照片输入正确),但所有输入都存在;并在控制器中使用完全相同的强参数;通过控制器中的 update
方法会产生参数错误。这是 update
方法:
def update
@product = Product.find(params[:id])
@product = Product.update(product_params) # here is where the error happens
@all_sizes = Size.all
@all_colors = Color.all
@all_patterns = Pattern.all
@all_materials = Material.all
if @product.save
5.times.with_index do |_, i|
if params["material_id_0#{(i + 1)}"] != ""
ProductMaterial.create!(product_id: @product.id,
material_id: params["material_id_0#{(i + 1)}"].to_i,
percent: params["material_percent_0#{(i + 1)}"].to_i)
else
break
end
end
redirect_to @product
else
render :edit
end
end
这是在服务器中看到的错误的确切语法:
ArgumentError (wrong number of arguments (given 1, expected 2)):
app/controllers/products_controller.rb:72:in `update'
这里
@product = Product.update(product_params)
您正在尝试调用产品 class 本身的实例方法 update
。 new
是一种 class 方法,因此在创建操作中效果很好。应该如何:
def update
@product = Product.find(params[:id])
# here you define different @all instances
# you don't need to update and save separately, because instance is saved already
# if you call update on it and update goes well
if @product.update(product_params)
# here goes the rest controller code
我正在使用 Rails 5.2 并构建一个 ecomm 站点。
我的 new.html.erb
页面有一个 simple_form,其中包含 Product
字段以及在强参数和新实例创建之外处理的其他参数。
表单的一个功能是 eventListener
,它根据四个输入值自动创建 :sku
。隐藏产品编号、sku 和实时状态。
这里是html.erb
的简化版本:
<%= simple_form_for @new_product do |f| %>
<%= f.error_notification %>
<%= f.input :name%>
<%= f.association :size, collection: @all_sizes.map{ |s| [s.name, s.id, {'data-code-num' => s.code_num}]}, input_html:{class: 'sku-suffix-component'} %>
<%= f.association :color, collection: @all_colors.map{ |s| [s.name, s.id, {'data-code-num' => s.code_num}]}, input_html:{class: 'sku-suffix-component'} %>
<%= f.association :pattern, collection: @all_patterns.map{ |s| [s.name, s.id, {'data-code-num' => s.code_num}]}, input_html:{class: 'sku-suffix-component'} %>
<%= f.input :product_number, as: :hidden, input_html:{ value: @new_product.product_number, class: "sku-suffix-component" } %>
<%= f.input :sku,as: :hidden, html:{id: "new-product-form-sku-input"} %>
<%= f.input :live_status, as: :hidden, :input_html => { :value => @new_product.live_status } %>
<%= f.input :description, as: :text %>
<%= f.association :brand%>
<%= f.association :style %>
<%= f.input :price %>
<%= f.input :quantity, input_html:{value: 1}%>
<%= f.association :segment %>
<%= f.association :main_category %>
<%= f.association :category %>
<%= f.association :country, class: '' %>
<!-- Here are some inputs for adding records to a material join table -->
<!-- And the names of the inputs are dynamically created -->
<% 5.times.with_index do |_, i| %>
<% num = i + 1 %>
<label class="form-control-label integer" for="material_percent_id_<%= num < 10 ? "0" + num.to_s : num.to_s %>">Percent</label>
<input class="form-control numeric integer required" type="number" step="1" name="material_percent_<%= num < 10 ? "0" + num.to_s : num.to_s %>" id="material_percent_id_<%= num < 10 ? "0" + num.to_s : num.to_s %>">
<label class="form-control-label select" for="material_id_id_<%= num < 10 ? "0" + num.to_s : num.to_s %>">Material Component #<%= num %> </label>
<select class="form-control select" name="material_id_<%= num < 10 ? "0" + num.to_s : num.to_s %>" id="material_id_id_<%= num < 10 ? "0" + num.to_s : num.to_s %>">
<option value=""></option>
<% @all_materials.each do |material| %>
<option value="<%= material.id %>"><%= material.name %></option>
<% end %>
</select>
<% end %>
<!-- Here are some inputs for adding multiple photos to the products using active_storage -->
<% (1..8).each do |i| %>
<%= f.label "Photo [#{i}]" %>
<%= f.file_field :photos, multiple: true %>
<% end %>
<%= f.button :submit %>
<% end %>
使用此 simple_form
创建新产品以及连接 table 中的实例通过 create method
工作正常,如下所示:
def create
@all_sizes = Size.all
@all_colors = Color.all
@all_patterns = Pattern.all
@new_product = Product.new(product_params)
@all_materials = Material.all
if @new_product.save
5.times.with_index do |_, i|
if params["material_id_0#{(i + 1)}"] != ""
ProductMaterial.create!(product_id: @new_product.id,
material_id: params["material_id_0#{(i + 1)}"].to_i,
percent: params["material_percent_0#{(i + 1)}"].to_i)
else
break
end
end
redirect_to @new_product
else
render :new
end
end
使用几乎完全相同的形式(添加了一些代码以动态呈现连接 table 输入和照片输入正确),但所有输入都存在;并在控制器中使用完全相同的强参数;通过控制器中的 update
方法会产生参数错误。这是 update
方法:
def update
@product = Product.find(params[:id])
@product = Product.update(product_params) # here is where the error happens
@all_sizes = Size.all
@all_colors = Color.all
@all_patterns = Pattern.all
@all_materials = Material.all
if @product.save
5.times.with_index do |_, i|
if params["material_id_0#{(i + 1)}"] != ""
ProductMaterial.create!(product_id: @product.id,
material_id: params["material_id_0#{(i + 1)}"].to_i,
percent: params["material_percent_0#{(i + 1)}"].to_i)
else
break
end
end
redirect_to @product
else
render :edit
end
end
这是在服务器中看到的错误的确切语法:
ArgumentError (wrong number of arguments (given 1, expected 2)):
app/controllers/products_controller.rb:72:in `update'
这里
@product = Product.update(product_params)
您正在尝试调用产品 class 本身的实例方法 update
。 new
是一种 class 方法,因此在创建操作中效果很好。应该如何:
def update
@product = Product.find(params[:id])
# here you define different @all instances
# you don't need to update and save separately, because instance is saved already
# if you call update on it and update goes well
if @product.update(product_params)
# here goes the rest controller code