Rails 5:缺少参数且无法呈现编辑或未保存的更新/不允许的参数
Rails 5: Parameter Missing and Fail to Render Edit OR Unsaved Update / Unpermitted Parameters
使用 Devise,Rails 5.0.6,Sqlite 3,简单表单,Active Record 5.0。
自从在整个 Stack Overflow 中查找许多类似 problems/solutions 以来,在两个参数问题之间反复出现。在这两种情况下,显示为在 Ruby 错误或服务器日志中传递的唯一参数是 {id => "n" }(其中 n 是任何产品的正确编号)而不是完整的参数列表。
我觉得我设置 Devise 的方式或设置简单表单的方式有问题...但不确定。请帮忙!!!
简洁比较:
问题 #1:缺少参数,无法呈现产品#Edit
- 当我在 product_parameters 方法中需要参数时会发生这种情况。
- Ruby 无法呈现并在 ProductsController#edit 错误中拉出 ActionController::ParameterMissing。
- 请求参数:{"id"=>"2"}
问题 #2:编辑表单呈现,但产品记录不更新
- 没有错误,闪现消息确认成功并重新呈现产品展示
属性没有更新
Rails 服务器日志说:
不允许的参数:utf8、_method、authenticity_token、产品、
犯罪
产品参数:“2”} 允许:true>重定向到 http://localhost:3000/products/2
完成 302 在 8 毫秒内找到(ActiveRecord:0.4 毫秒)
这是我的代码:
产品型号:
class Product < ApplicationRecord
belongs_to :category
has_many :product_specs
has_many :specifications, through: :product_specs
end
产品负责人
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
@specification = Specification.new
end
def create
@message = Message.new
@message.build_company
@categories = Category.all
@product = Product.new(product_parameters)
@product.category_id = product_parameters[:category_id]
if @product.save!
redirect_to product_path(@product)
else
render "new"
puts "fail"
end
end
def show
@categories = Category.all
@message = Message.new
@message.build_company
end
def edit
@message = Message.new
@message.build_company
@categories = Category.all
@product.update(product_parameters)
end
def update
if @product.update(product_parameters)
# @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])
end
def product_parameters
# Problem 1 => Keep 'require' : Edit Form Fails to Render, ActionController::ParameterMissing in ProductsController#edit
# params.require(:product).permit(:id, :name, :description, :picture, :product_spec_id)
# Problem 2 => Delete 'require': Edit Form renders, but fails to update Product record
params.permit(:id, :name, :description, :picture, :product_spec_id)
end
end
路线
Rails.application.routes.draw do
devise_for :users
root to: 'pages#index', as: :home
get 'contact', to: 'messages#new', as: :contact
get 'about', to: 'pages#about', as: :about
get 'exa', to: 'pages#exa', as: :exa
get 'services', to: 'pages#services', as: :services
get 'messages', to: 'messages#show', as: :contactconfirm
resources 'products'
resources 'categories'
resources 'posts'
resources 'messages' do
resources :companies, only: [:new, :create, :show, :edit, :update]
resources :industries, only: [:index, :show]
end
end
Products/Edit.html.erb
<%= 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_admin_actions">
<div>Add A Specification</div>
</div>
<%= product.button :submit, "Save This Product" %>
<% end %>
您不应在编辑操作中更新,此操作仅用于表单呈现。移除
@product.update(product_parameters)
来自编辑操作的行。
product_parameters
应该有 require 部分才能正确更新产品
从编辑页面删除更新产品。
def edit
@message = Message.new
@message.build_company
@categories = Category.all
end
product_parameters方法应该是。
def product_parameters
params.require(:product).permit(:id, :name, :description, :picture,
:product_spec_id)
#params.require(:product).permit! for permitting all attributes.
end
您收到该错误是因为您试图在无效的编辑方法中进行更新。在编辑方法中,如何获得允许的参数?如果没有传递任何参数。
除非将其呈现给另一个模板,否则每个操作本身就是模板页面。
所以,products#edit
=> products/edit.html.erb
In edit.html.erb
包含完全来自 products_controller's
edit
操作 -
的预填充数据
提交编辑表单后,数据将发送到 update
操作,并会在 products#update
操作上更新数据。
所以更新发生在更新操作而不是编辑操作,即
def edit
@message = Message.new
@message.build_company
@categories = Category.all
#@product.update(product_parameters)
end
使用 Devise,Rails 5.0.6,Sqlite 3,简单表单,Active Record 5.0。
自从在整个 Stack Overflow 中查找许多类似 problems/solutions 以来,在两个参数问题之间反复出现。在这两种情况下,显示为在 Ruby 错误或服务器日志中传递的唯一参数是 {id => "n" }(其中 n 是任何产品的正确编号)而不是完整的参数列表。
我觉得我设置 Devise 的方式或设置简单表单的方式有问题...但不确定。请帮忙!!!
简洁比较:
问题 #1:缺少参数,无法呈现产品#Edit
- 当我在 product_parameters 方法中需要参数时会发生这种情况。
- Ruby 无法呈现并在 ProductsController#edit 错误中拉出 ActionController::ParameterMissing。
- 请求参数:{"id"=>"2"}
问题 #2:编辑表单呈现,但产品记录不更新
- 没有错误,闪现消息确认成功并重新呈现产品展示
属性没有更新
Rails 服务器日志说:
不允许的参数:utf8、_method、authenticity_token、产品、 犯罪 产品参数:“2”} 允许:true>重定向到 http://localhost:3000/products/2 完成 302 在 8 毫秒内找到(ActiveRecord:0.4 毫秒)
这是我的代码:
产品型号:
class Product < ApplicationRecord
belongs_to :category
has_many :product_specs
has_many :specifications, through: :product_specs
end
产品负责人
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
@specification = Specification.new
end
def create
@message = Message.new
@message.build_company
@categories = Category.all
@product = Product.new(product_parameters)
@product.category_id = product_parameters[:category_id]
if @product.save!
redirect_to product_path(@product)
else
render "new"
puts "fail"
end
end
def show
@categories = Category.all
@message = Message.new
@message.build_company
end
def edit
@message = Message.new
@message.build_company
@categories = Category.all
@product.update(product_parameters)
end
def update
if @product.update(product_parameters)
# @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])
end
def product_parameters
# Problem 1 => Keep 'require' : Edit Form Fails to Render, ActionController::ParameterMissing in ProductsController#edit
# params.require(:product).permit(:id, :name, :description, :picture, :product_spec_id)
# Problem 2 => Delete 'require': Edit Form renders, but fails to update Product record
params.permit(:id, :name, :description, :picture, :product_spec_id)
end
end
路线
Rails.application.routes.draw do
devise_for :users
root to: 'pages#index', as: :home
get 'contact', to: 'messages#new', as: :contact
get 'about', to: 'pages#about', as: :about
get 'exa', to: 'pages#exa', as: :exa
get 'services', to: 'pages#services', as: :services
get 'messages', to: 'messages#show', as: :contactconfirm
resources 'products'
resources 'categories'
resources 'posts'
resources 'messages' do
resources :companies, only: [:new, :create, :show, :edit, :update]
resources :industries, only: [:index, :show]
end
end
Products/Edit.html.erb
<%= 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_admin_actions">
<div>Add A Specification</div>
</div>
<%= product.button :submit, "Save This Product" %>
<% end %>
您不应在编辑操作中更新,此操作仅用于表单呈现。移除
@product.update(product_parameters)
来自编辑操作的行。
product_parameters
应该有 require 部分才能正确更新产品
从编辑页面删除更新产品。
def edit
@message = Message.new
@message.build_company
@categories = Category.all
end
product_parameters方法应该是。
def product_parameters
params.require(:product).permit(:id, :name, :description, :picture,
:product_spec_id)
#params.require(:product).permit! for permitting all attributes.
end
您收到该错误是因为您试图在无效的编辑方法中进行更新。在编辑方法中,如何获得允许的参数?如果没有传递任何参数。
除非将其呈现给另一个模板,否则每个操作本身就是模板页面。
所以,products#edit
=> products/edit.html.erb
In edit.html.erb
包含完全来自 products_controller's
edit
操作 -
提交编辑表单后,数据将发送到 update
操作,并会在 products#update
操作上更新数据。
所以更新发生在更新操作而不是编辑操作,即
def edit
@message = Message.new
@message.build_company
@categories = Category.all
#@product.update(product_parameters)
end