yaycake
yaycake

Reputation: 3

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

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

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

Upvotes: 0

Views: 1071

Answers (3)

Anand
Anand

Reputation: 6531

Every action is itself template page unless it's being rendered to another template.

So, products#edit => products/edit.html.erb

In edit.html.erb contains pre-filled data which is exactly coming from products_controller's edit action -

after submitting edit form data will be sent to update action and it will update data on products#update action.

So updation is happening at update action not edit action , i.e

  def edit
    @message = Message.new
    @message.build_company
    @categories = Category.all
    #@product.update(product_parameters)
  end

Upvotes: 0

Vishal
Vishal

Reputation: 818

Remove update product from the edit page.

def edit
    @message = Message.new
    @message.build_company
    @categories = Category.all
end

product_parameters method should be.

def product_parameters
  params.require(:product).permit(:id, :name, :description, :picture, 
                                  :product_spec_id)
  #params.require(:product).permit! for permitting all attributes. 
end

You are getting that error because you are trying to update in edit method which is not valid. In the edit method, how can you get permitted params? if there are not passed any params.

Upvotes: 1

Vasilisa
Vasilisa

Reputation: 4640

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

Upvotes: 1

Related Questions