Ruby on Rails 5,简单表格
产品通过ProductSpecs有许多规格
在Product#Edit中,我想添加新规范。
如果Specifications.save成功,请退回产品。它重新发布产品并闪现“成功”,但新规范并未持续存在。
日志表示未经许可的参数 - 不确定如何更正我的product_parameters。我试过{product_specs => []}无济于事。
任何帮助将不胜感激!
日志:
Started PATCH "/products/2" for 127.0.0.1 at 2019-03-07 14:44:24 +0800
Processing by ProductsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"f/wU9o1Fi8jXlTDCiJF93xMXFlaRH6sKx9+lNyg4ZGthVGkhPMrLwES/bEgeeHTHXdXaoolj67FOnGqqULtysg==", "product"=>{"name"=>"Notebooks", "description"=>"Handheld military and medical devices are built to operate in a variety of environments and also built to last.asdfasdfasdf", "category_id"=>"1", "product_spec"=>{"specification"=>{"name"=>"COLD", "low_value"=>"1", "high_value"=>"22", "unit"=>"volts"}}}, "commit"=>"Add New Spec", "id"=>"2"}
Product Load (0.1ms) SELECT "products".* FROM "products" WHERE "products"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]]
Setting the product: Notebooks
#<Product id: 2, name: "Notebooks", description: "Handheld military and medical devices are built to...", picture: nil, created_at: "2019-02-20 06:43:20", updated_at: "2019-03-07 05:53:37", iconblack: "icons/products/icon_IPC_black.png", iconwhite: nil, iconyellow: nil, category_id: 1>Unpermitted parameter: product_spec
(0.1ms) begin transaction
Category Load (0.2ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
(0.1ms) commit transaction
SUPPOSEDLY UPDATING
Unpermitted parameter: product_spec
product parameters: <ActionController::Parameters {"name"=>"Notebooks", "description"=>"Handheld military and medical devices are built to operate in a variety of environments and also built to last.asdfasdfasdf", "category_id"=>"1"} permitted: true>Redirected to http://localhost:3000/products/2
Completed 302 Found in 7ms (ActiveRecord: 0.5ms)
Started GET "/products/2" for 127.0.0.1 at 2019-03-07 14:44:24 +0800
Processing by ProductsController#show as HTML
产品控制器:
class ProductsController < ApplicationController
# before_action :set_category, only: [:new, :create]
before_action :set_product, only: [:edit, :show, :update, :destroy]
def index
@products = Product.all
@categories = Category.all
@message = Message.new
@message.build_company
end
def new
@product = Product.new
@categories = Category.all
@message = Message.new
@message.build_company
@product.specifications.build
# setting product stuff for testing
@product.picture = "products/IPC_tablet.png"
@product.iconblack = "icons/products/icon_IPC_black.png"
end
def create
@message = Message.new
@message.build_company
@categories = Category.all
@product = Product.new(product_parameters)
@product.category_id = product_parameters[:category_id]
@product_spec = ProductSpec.new
@new_spec= Specification.new
if @product.save!
flash[:success] = "You have saved the #{@product.name} product"
redirect_to product_path(@product)
else
flash.now[:error] = "Product was not saved"
render "new"
end
end
def show
@product = Product.find(params[:id])
@categories = Category.all
@message = Message.new
@message.build_company
@product_specs = @product.product_specs
end
def edit
@message = Message.new
@message.build_company
@categories = Category.all
# To create a new specification through product spec
@product_spec = ProductSpec.new
@new_spec= Specification.new
@product_spec.product = @product
@product_spec.specification = @new_spec
end
def update
# puts "in update product, product parameters: #{product_parameters}"
# puts product_parameters
if @product.update(product_parameters)
flash[:success] = "You have updated the #{@product.name} product"
puts "SUPPOSEDLY UPDATING"
print "product parameters: #{product_parameters.inspect}"
redirect_to product_path(@product)
else
# puts "SUPPOSEDLY NOT UPDATING"
flash.now[:error] = "You have not updated #{@product.name}"
render :edit
end
end
private
def build_company
@message.build_company
end
def set_product
@product = Product.find(params[:id])
puts "Setting the product: #{@product.name}"
print @product.inspect
end
def find_category
@category = Category.find(params[:category_id])
end
def product_parameters
params.require(:product).permit(
:id,
:name,
:description,
:picture,
:category_id,
category: [
:id
],
product_specs: [
{:specification => [] } ]
)
end
end
产品规格控制器:
class ProductSpecsController < ApplicationController
before_action :find_product, only: [:new, :create, :destroy, :set_product_spec]
before_action :set_product_spec, only: [:destroy, :show]
def new
@product_spec = ProductSpec.new(:product_id => params[:product_id])
end
def create
end
def destroy
@product = Product.find(params[:product_id])
if @product_spec.destroy
flash[:success] = "Product Specification Deleted"
redirect_to product_path(@product.id)
else
flash[:error] = "Oops! Something went wrong"
redirect_to product_path
end
end
private
def find_product
@product = Product.find(params[:product_id])
end
def set_specification
end
def set_product_spec
@product_spec = ProductSpec.find_by(params[:product_id])
end
end
规格控制器:
class SpecificationsController < ApplicationController
before_action :set_specification, only: [:edit, :show, :update, :destroy]
def new
end
def create
end
def destroy
end
private
def set_specification
@specification = Specification.find(params[:id])
end
end
产品#编辑表格/查看:
<%= simple_form_for @product do |product| %>
<h4 class="product_name">
<%= product.input :name, placeholder: "Product Name" %>
</h4>
<div class="product_picture">
<%= image_tag("products/IPC_tablet.png") %>
</div>
<div class="product_description">
<strong>Description</strong>
<p class="font-size-12">
<%= product.input :description, label: false %>
</p>
<%= product.association :category, prompt: "Select Category" %>
</div>
<div class="product_specifications">
<strong>Specifications</strong>
<!-- RENDER THRU PRODUCT SPECS, EACH EXISTING SPECIFICATION -->
<% if @product_specs %>
<%= product.simple_fields_for :product_specs do |ps| %>
<%= ps.simple_fields_for :specification do |spec| %>
<div class="add_specification">
<div class="specification_fields">
<%= spec.input :name, label: false, input_html: { class: 'spec_input_name' }, placeholder: "Spec" %>
<%= spec.input :low_value, input_html: { class: 'spec_input_values' }, label: false, placeholder:"Lowest Value" %>
<%= spec.input :high_value, input_html: { class: 'spec_input_values' }, label: false, placeholder: "Highest Value" %>
<%= spec.input :unit, label: false, input_html: { class: 'spec_input_values' }, placeholder:"Unit" %>
<%= spec.button :submit, "Save Spec" %>
</div>
</div>
<% end %>
<% end %>
<div>
<strong>Add A New Specification</strong>
</div>
<% end %>
<!-- - - - - - ADD A NEW SPECIFICATION -->
<%= product.simple_fields_for @product_spec do |newps| %>
<%= newps.simple_fields_for @new_spec do |newspec| %>
<div class="add_specification">
<div class="specification_fields">
<%= newspec.input :name, label: false, input_html: { class: 'spec_input_name' }, placeholder: "Spec Name" %>
<%= newspec.input :low_value, label: false, input_html: { class: 'spec_input_values' }, placeholder: "Lowest Value" %>
<%= newspec.input :high_value, label: false, input_html: { class: 'spec_input_values' }, placeholder: "Highest Value" %>
<%= newspec.input :unit, label: false, input_html: { class: 'spec_input_values' }, placeholder: "Unit" %>
<%= newspec.button :submit, "Add New Spec" %>
<% end %>
</div>
<% end %>
</div>
<div class="product_admin_actions">
<%= product.button :submit, "Save This Product" %>
</div>
<% end %>
我认为理解accepts_nested_attributes_for
如何在Rails中工作的问题。我会试着清楚地解释一下。
模型之间的关系也是另一个重要的部分。如果我们接受这样的现实:Product -> ProductSpec -> Specification
解决方案必须是这样的。
# models/product.rb
class Product < ApplicationRecord
has_many :product_specs
accepts_nested_attributes_for :product_specs
end
# models/product_spec.rb
class ProductSpec < ApplicationRecord
has_many :specifications
accepts_nested_attributes_for :specifications
end
# controllers/products_controller.rb
class ProductsController < ApplicationController
...
def create
@proudct = Product.create(product_params)
end
private
def product_params
params.require(:product).permit(
:id,
:name,
:description,
:picture,
:category_id,
product_specs_attributes: [:id,
specifications_attributes: [:id, :name, :low_value, :high_value]
])
end
end
您的视图字段看起来正确。