Сохранение коллекции объектов rails 4 (сильные параметры)

В настоящее время я работаю над бэкэндом магазина. Клиент хочет иметь возможность видеть список всех продуктов и обновлять стоимость запасов для всех продуктов в одной отправке формы. У меня есть рабочее решение, но оно очень «хакерское» и создает много проблем. Я новичок в Ruby on Rails и веб-разработке в целом, поэтому я все еще изучаю некоторые фундаментальные соглашения, а что нет.

Я вставлю свое рабочее решение, а затем попытаюсь объяснить проблему, которая у меня есть:

class Product < ActiveRecord::Base
   has_many :stocks
   ...
end

class Stock < ActiveRecord::Base
   belongs_to :product
   ...
end

stock_controller.rb

class StocksController < ApplicationController

  def index
    @products = Product.all.includes(:stocks)
  end
...
  def update_current      
    @stock_params = params[:stock]
    @stock_params.each do |stock_params|
      params.permit(:current_stock, :product_id)
      @stock = Stock.new(stock_params)
      @stock.save
  end
    redirect_to stocks_path, notice: 'Stocks were successfully updated'
 end        
...

stocks.index.html.erb

...
<%= form_tag url_for(:action => 'update_current') do |f| %>
  <% @products.each do |product| %>
    <tr>
      <td><%= product.product_name %></td>
      <td><%= product.minimum_stock %></td>
      <td><%= text_field_tag "stock[][current_stock]", product.stocks.last.current_stock %></td>
  <%= hidden_field_tag "stock[][product_id]", product.stocks.last.product_id %>
    </tr>
    <% end %>
  <%= submit_tag 'save' %>
 <% end %>
...

Когда я нажимаю кнопку отправки, параметры устанавливаются такими, какими они должны быть:

консоль :

Started POST "/stocks/update_current" for 127.0.0.1 at 2013-10-24 11:54:03 +0100
Processing by StocksController#update_current as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"NlabBuwI06t+YN5O6p7dm+Zg2Bwc9uXrKUdWaBqNs9w=", "stock"=>[{"current_stock"=>"1", "product_id"=>"1"}, {"current_stock"=>"2", "product_id"=>"2"}, {"current_stock"=>"3", "product_id"=>"24"}, {"current_stock"=>"4", "product_id"=>"25"}, {"current_stock"=>"5", "product_id"=>"23"}, {"current_stock"=>"6", "product_id"=>"21"}, {"current_stock"=>"7", "product_id"=>"19"}, {"current_stock"=>"8", "product_id"=>"22"}, {"current_stock"=>"9", "product_id"=>"5"}], "commit"=>"save"}
Unpermitted parameters: utf8, authenticity_token, stock, commit
 (0.2ms)  BEGIN
SQL (136.6ms)  INSERT INTO "stocks" ("created_at", "current_stock", "product_id", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["created_at", Thu, 24 Oct 2013 10:54:03 UTC +00:00], ["current_stock", 1], ["product_id", 1], ["updated_at", Thu, 24 Oct 2013 10:54:03 UTC +00:00]]
(24.2ms)  COMMIT
Unpermitted parameters: utf8, authenticity_token, stock, commit
(0.2ms)  BEGIN
SQL (0.7ms)  INSERT INTO "stocks" ("created_at", "current_stock", "product_id", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["created_at", Thu, 24 Oct 2013 10:54:03 UTC +00:00], ["current_stock", 2], ["product_id", 2], ["updated_at", Thu, 24 Oct 2013 10:54:03 UTC +00:00]]
(0.7ms)  COMMIT
Unpermitted parameters: utf8, authenticity_token, stock, commit
(0.1ms)  BEGIN
SQL (0.4ms)  INSERT INTO "stocks" ("created_at", "current_stock", "product_id",      "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["created_at", Thu, 24 Oct 2013  10:54:03 UTC +00:00], ["current_stock", 3], ["product_id", 24], ["updated_at", Thu, 24 Oct  2013 10:54:03 UTC +00:00]]
  (0.6ms)  COMMIT

Как вы можете видеть из журнала, параметр authentication_token и другие параметры не разрешены. Теперь я понимаю назначение токена и других параметров, чего не знаю, почему именно я столкнулся с этой проблемой.

Я предполагаю, что я разрешаю параметры. Я не понимаю, как сказать strong_params разрешить массив хэшей: stock => [{:current_stock, :product_id},{:current_stock, :product_id}, ..., ....]. params.permit(stock: [:current_stock, :product_id]) ???

В этом случае не имеет смысла размещать запасы под продуктом, так как я работаю с набором продуктов, а не с одним продуктом.

В идеальном мире я хотел бы иметь возможность вставлять новые значения запасов для всех продуктов в одну отправку и сохранять в базе данных с помощью одного запроса. Я чувствую, что Ajax может быть жизнеспособным решением, но опять же, пока я полностью не пойму, что происходит, я не хочу еще больше запутывать вещи.

Любые решения или советы очень ценятся. Я надеюсь, что вышеизложенное имеет смысл! Иногда очень трудно сформулировать эти вещи.


person Shaun Gordon    schedule 24.10.2013    source источник


Ответы (1)


Это может быть или не быть вашей проблемой, но в вашем методе update_current разве это не должно быть stock_params.permit(:current_stock, :product_id) ? Также второстепенный момент, почему у вас есть |f| в вашем form_tag, если вы его не используете.

person Chemist    schedule 24.10.2013
comment
ха-ха, ах да, я думаю, что поставил это раньше, когда использовал form_for, и просто был небрежным, я удалю это, спасибо :)... params - это экземпляр ActionController:: Parameters (строгие параметры), где мой stock_params - не так, если бы я сделал stock_params.permit, я бы получил NoMethodError - person Shaun Gordon; 24.10.2013