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

问题 #2:编辑表单呈现,但产品记录不更新

这是我的代码:

产品型号:

    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