Search code examples
ruby-on-railsdevisesimple-formstrong-parameters

Rails 5: Parameter Missing and Fail to Render Edit OR Unsaved Update / Unpermitted Parameters


Using Devise , Rails 5.0.6, Sqlite 3, Simple Form, Active Record 5.0.

Bouncing between two parameter problems since looking up many similar problems/solutions throughout Stack Overflow. In both cases, the only parameters that show as being passed on the Ruby errors or server logs is the {id => "n" } (where n is the correct number of any product) instead of the full list of parameters.

I feel like there's a problem with either how I set up Devise or how I've set up the Simple Form... but not sure. Please help!!!

Succinct comparison:

Problem #1: Parameter Missing, Fails To Render Product#Edit

  • This occurs when I require params in my product_parameters method.
  • Ruby fails to render and pulls an ActionController::ParameterMissing in ProductsController#edit error.
  • Request Parameters: {"id"=>"2"}

Problem #2: Edit form renders, but Product record does not update

  • No error, flash message confirms success & rerenders Product Show
  • Noupdate to the attributes

  • Rails server log says:

    Unpermitted parameters: utf8, _method, authenticity_token, product, commit product parameters: "2"} permitted: true>Redirected to http://localhost:3000/products/2 Completed 302 Found in 8ms (ActiveRecord: 0.4ms)

Here is my code:

Product Model:

    class Product < ApplicationRecord 
belongs_to :category

  has_many :product_specs
  has_many :specifications, through: :product_specs
end

Product Controller

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

Routes

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 %>

Solution

  • You shouldn't update in edit action, this action is for form rendering only. Remove

    @product.update(product_parameters)
    

    line from the edit action.

    product_parameters should be with require part to update product correctly