I understand that this issue has been raised several times, but I can't find to find a way around..
I am using this solution to create a multi-step form without the Wicked gem: Best way to make Multi-Steps form in Rails 5
It seems that I am able to create a product when I use binding.pry
and enter the needed commands inside my rails console.
However, the app in itself does not function and I can't manage to work around it..
Two issues throw the ActionController::ParameterMissing error:
1) First, anytime I intend to press the back_button it raises ParameterMissing error (see at the end for exact error message).
2) When I get to the last_step of the form, it displays all the needed information, but will neither create nor save new products (also ParameterMissing).
Here is my code:
Routes
get 'products/new', to: 'products#new', as: 'new_product'
post 'products', to: 'products#create', as: 'create_new_product'
resources :categories, only: [:index, :show, :new, :edit, :destroy] do
resources :sub_categories, only: [:index, :show, :new, :edit, :destroy]
resources :products, only: [:index, :show, :destroy]
end
Products Controller
class ProductsController < ApplicationController
skip_after_action :verify_authorized, except: :index, unless: :skip_pundit?
skip_after_action :verify_policy_scoped, only: :index, unless: :skip_pundit?
before_action :set_category, only: [:index, :show]
def new
session[:product_params] ||= {}
authorize @product = Product.new(session[:product_params])
@product.current_step = session[:product_step]
@product.user = current_user
end
def create
session[:product_params].deep_merge!(params_product) if params_product
authorize @product = Product.new(session[:product_params])
@product.current_step = session[:product_step]
@product.user = current_user
if @product.valid?
if params[:back_button]
@product.previous_step
elsif @product.last_step?
if @product.all_valid?
@product.save!
flash[:notice] = 'Your product was created successfully'
redirect_to newest_products_path && return
end
else
@product.next_step
end
end
session[:product_step] = @product.current_step
if @product.new_record?
return render :new
else
session[:product_step] = session[:product_params] = nil
end
end
private
def set_category
authorize @category = Category.find(params[:category_id])
end
def params_product
params.require(:product).permit(:name, :price, :description, :category, :category_id,
:sub_category, :sub_category_id, :user, :user_id, :id)
end
end
Product Model
class Product < ApplicationRecord
attr_writer :current_step
belongs_to :user, optional: true
belongs_to :sub_category
belongs_to :category, inverse_of: :products
validates :category, presence: true
validates_presence_of :name, :category_id, if: lambda { |e| e.current_step == "card" }
validates_presence_of :sub_category_id, :description, :price, if: lambda { |e| e.current_step == "details" }
def current_step
@current_step || steps.first
end
def steps
%w[card details confirmation]
end
def next_step
self.current_step = steps[steps.index(current_step) + 1]
end
def previous_step
self.current_step = steps[steps.index(current_step) - 1]
end
def first_step?
current_step == steps.first
end
def last_step?
current_step == steps.last
end
def all_valid?
steps.all? do |step|
self.current_step = step
valid?
end
end
end
New Products View
<%= form_for @product, url: create_new_product_path do |f| %>
<%= render "#{@product.current_step}_step", :f => f %>
<div class="bottom-signup">
<%= f.submit "Continue" unless @product.last_step? %>
<%= f.submit "Submit Product" if @product.last_step? %>
<%= f.submit "Back", :name => "back_button" unless @product.first_step? %>
</div>
<% end %>
Here is the exact error that is thrown by ActionController:
ActionController::ParameterMissing in ProductsController#create
param is missing or the value is empty: product
#around ligne (96)
95 def params_product
96 params.require(:product).permit(:name, :price, :description, :category, :category_id,
97 :sub_category, :sub_category_id, :user, :user_id, :id)
98 end
And finally, here is what appears if I raise params.inspect:
params.inspect
=> "<ActionController::Parameters {\"utf8\"=>\"✓\", \"authenticity_token\"=>\"AHfNwkeFOWBeEup+fCCvfZv1RowuP/YULHjo8kTnzer5YNCY7lMYAKzrrWJBVMcfOO+P1GmZGgi9PDpa/09rzw==\", \"commit\"=>\"Submit Product\", \"controller\"=>\"products\", \"action\"=>\"create\"} permitted: false>"
If someone understands where I'm wrong, I'd be more than glad to discuss it!
Thanks in advance.
Best, Ist