Почему мой метод rails update использует те же сильные параметры, что и мой метод create, и выдает ошибку аргумента? - PullRequest
0 голосов
/ 25 декабря 2018

Я использую Rails 5.2 и создаю сайт ecomm.

Моя страница new.html.erb содержит simple_form с комбинацией полей Product, а также других параметров, которые обрабатываются вне сильных параметров исоздание нового экземпляра.

Одной из особенностей формы является eventListener, который автоматически создает :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 работает нормально,наряду с экземплярами в таблице соединений через 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

Использование почти точно такой же формы (добавлен некоторый код для динамического рендеринга входов в таблицу соединений и корректный ввод фотографий),но все входы присутствуют;и используя точно такие же сильные параметры в контроллере;Прохождение метода 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'

enter image description here

1 Ответ

0 голосов
/ 25 декабря 2018

Здесь

@product = Product.update(product_params)

вы пытаетесь вызвать метод экземпляра update для самого класса Product.new - это метод класса, поэтому он хорошо работает при создании действия.Как и должно быть:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...