Unpermitted parameter error whereas parameter specified in params in controller - ruby-on-rails

I have a product model which has a many to many association with a category model through join model category_product
I have a product/new.html.slim
=simple_form_for #product, html: { multipart: true } do |t|
= t.error_notification
div class="form-group"
= t.input :name, label: 'Nom',equired: true, input_html: { class: 'form-control' }
div class="form-group"
= t.input :description, label: 'Description', required: true, input_html: { class: 'form-control' }
div class="form-group"
= t.input :price, label: 'Prix', required: true, input_html: { class: 'form-control' }
div class="form-group"
= t.input :weight, label: 'Poids', required: true, input_html: { class: 'form-control' }
div class="form-group"
= t.association :categories, as: :check_boxes, label: "Catégories"
= t.button :submit, value: "Valider", class: "btn-success marge-bas"
when I submit my form I get the following error :
found unpermitted parameter: category_ids
though in my ProductController I have permitted category_ids :
def product_params
params.require(:product).permit(
:category_ids,
:name,
:price,
:description,
:weight,
:picture,
:picture1,
:picture2,
:picture3,
)
end
When I check my params category_ids is an array of strings
"category_ids"=>["1", "2", "5", ""]
What am I doing wrong ?

Try rewriting product_params to:
def product_params
params.require(:product).permit(:name, ... :picture3, :category_ids => [])
end
Setting the category_ids to be an array at the end of your list of permitted params should resolve this error.
Hope it helps!

I ran into this "Unpermitted parameter: category_ids" error when working through the book, "Rails, Up And Running" and adding category_ids => [] fixed it. Thank you, Zoran!

Related

Ruby on Rail Nested Attributes do not save to database

I am trying to create a form that updates 2 tables - commission_type and commission_tier.
I created the models, controller and form but when I submit it, my commission_tier table does not update. Only my commission_type table updates.
Can someone take a look at my code and tell me what I am doing wrong? I have combed through my code trying to find the mistake, and I cannot find it.
My models
class CommissionType < ApplicationRecord
has_many :commission_tiers
accepts_nested_attributes_for :commission_tiers
end
class CommissionTier < ApplicationRecord
belongs_to :commission_types, optional: true
end
My controller
class Admin::CommissionTypesController < Admin::BaseController
def index
#commission_types = CommissionType.all
end
def new
#commission_type = CommissionType.new
#commission_type.commission_tiers.build
end
def create
#commission_type = CommissionType.new(commission_type_params)
if #commission_type.save
redirect_to admin_commission_types_index_path
else
render "new"
end
private
def commission_type_params
params.require(:commission_type).permit(:name, :active, :allow_mass_update, :plan,
commission_tiers_attributes: [:id, :increment_value, :rate, :commission_type_id])
end
end
My form
<%= simple_form_for #commission_type, url: admin_commission_types_index_path, wrapper: :bootstrap2, :html => { :class => 'form-horizontal' } do |f| %>
<fieldset>
<legend>Properties</legend>
<%= f.input :name, label: 'Commission Name' %>
<%= f.input :active, as: :boolean, label: 'Active?', label_html: { class: 'padding-top' } %>
<%= f.input :allow_mass_update, as: :boolean, label: 'Allow mass update?', label_html: { class: 'padding-top' } %>
<%= f.input :plan, input_html: {id: 'dropdown'},
label: 'Commission Type',
collection: [ ['Select One..', 'select'], ['Flat', 'flat'], ['Flat +', 'flat_plus' ], ['Promotional', 'promotional'], ['Straight', 'straight'], ['Waterfall', 'waterfall'], ['Sliding Scale', 'sliding_scale'] ],
selected: 'select'
%>
</fieldset>
<fieldset id="flat">
<legend>Flat Commission</legend>
<%= f.simple_fields_for :commission_tiers do |builder| %>
<%= builder.input :rate %>
<%= builder.input :increment_value %>
<% end %>
</fieldset>
My form is displaying and working
UPDATE
Some additional details
CommissionType column values = [:name, :active, :allow_mass_update, :plan]
CommissionTier column values = [:id, :increment_value, :rate, :commission_type_id]
Also, when I submit my form, here is an example of what my params are
<ActionController::Parameters {"name"=>"asdf", "active"=>"1", "allow_mass_update"=>"1", "plan"=>"flat", "commission_tiers_attributes"=><ActionController::Parameters {"0"=><ActionController::Parameters {"rate"=>"45"} permitted: true>} permitted: true>} permitted: true>

rails form send many rows from same instance

I have a form to create a teacher, and in this form a have a table where I register the subjects that they can teach and some experience related of it.
But I dont know how to do it, in model, in controller and in view, because a have add nested fields to my teacher form, and use nested_attributes in model, and permit it in controller. but I dont know how to do it..
Model
class Tutor < User
has_many :tutor_subjects
accepts_nested_attributes_for :tutor_subjects
end
In Controller i have the functions...
def create
#tutor = Tutor.new(tutor_params)
#tutor.save
end
def tutor_params
params.require(:tutor).permit(:email,
:first_name,
:last_name,
:gender,
:password,
tutor_subjects_attributes: [])
end
end
And the view
= simple_form_for [:admin, #tutor] do |f|
= f.error_notification
.col-md-8.col-sm-12
.form-inputs
= f.input :email
= f.input :password
= f.input :first_name
= f.input :last_name
= f.input :gender, collection: {Male: 1, Female: 2}, include_blank: "--Select gender--"
%h2.well.well-sm Subjects
%table.table
%thead
%tr
%th Subject
%th Experience
%th Options
%tbody#subjects
= f.simple_fields_for :tutor_subjects_attributes do |s|
%tr.subject0
%td
= s.input :subject_id, collection: Subject.all, label: false, include_blank: "--Select subject--", input_html: { id: "tutor_subjects_attributes_0_subject_id", name: 'tutor[tutor_subjects_attributes][0][subject_id]', class: "subject" }
%td
= s.input :experience, as: :text, label: false, input_html: { placeholder: "Type your experience", name: 'tutor[tutor_subjects_attributes][0][experience]', id: "tutor_subjects_attributes_0_experience" }
%td.options
= link_to :add_subject, "#", id: "add_subject", class: "btn btn-small btn-info"
I am not sure I understand your question right but it seems like you have problems dealing with strong parameters for nested attributes.
Your tutor_params should look like
def tutor_params
params.require(:tutor).permit(
:email,
...
tutor_subjects_attributes: [
:subject_id,
:experience
]
)
end
end

enum select in rails

I've got a problem with selecting enum value in form
here is a form
=form_for #ticket , remote: true do |f|
.errors
p
= f.label :name, class: 'label_hidden'
= f.text_field :name, placeholder:'Input your name', class:'form-control'
p
= f.label :email, class: 'label_hidden'
= f.email_field :email, placeholder:'Input your email', class:'form-control'
p
= f.label :department, class: 'label_hidden'
= f.select :department, Ticket.departments.keys , class:'form-control'
p
= f.submit 'Submit', class:'btn btn-default custom'
In my db I have a field department that is string type, also in a model I have
class Ticket < ActiveRecord::Base
enum department: [:issue, :qa, :promotion]
validates :name, :email, :subject, :body, :department, presence: true
end
When i send this form - in params everything is ok( the department param is there), also I have permitted this param in controller. Still I recieve "department can't be blank". Where I am wrong?
I suppose that you receive enum as a String, so you should convert it with setter method:
def department=(val)
self[:department] = val.to_sym
end

Rails adding error to :base not working as expected

I have a double nested form:
<%= simple_form_for #item, html: { class: "create-item-form" } do |item_builder| %>
<div class="well">
<%= item_builder.input :name, required: false, error: false, label: "item name" %>
<%= item_builder.input :description, as: :text, required: false, error: false, label: "How do users earn this item?" %>
<%= item_builder.input :tag_list, required: false, label: "Tags (these will help users find your item)" %>
<%= item_builder.simple_fields_for :user_items do |user_item_builder| %>
<%= user_item_builder.input :foo, as: :hidden, input_html: { value: "bar" } %>
<%= user_item_builder.simple_fields_for :user_item_images do |user_item_images_builder| %>
<%= user_item_images_builder.input :foo, as: :hidden, input_html: { value: "bar" } %>
<%= user_item_images_builder.input :picture, as: :file, required: false,
error: false, label: "Pictures of you earning this item",
input_html: { multiple: true,
name: "item[user_items_attributes][0][user_item_images_attributes][][picture]" } %>
<% end %>
<% end %>
</div>
<div class="clearfix">
<%= item_builder.submit 'Submit new item request', class: "btn btn-primary pull-right inherit-width" %>
</div>
<% end %>
When a user doesn't upload a file for the user_item_image I need to display an error message. I wrote a custom validation:
user_item_image.rb
class UserItemImage < ActiveRecord::Base
include PicturesHelper
attr_accessor :foo
mount_uploader :picture, PictureUploader
belongs_to :user_item
validate :picture_size
validate :has_picture
private
def has_picture
errors.add(:base, 'You must include at least one picture.') if picture.blank?
end
end
But I get the error message:
User items user item images base You must include at least one picture.
How can I rewrite the validation so that it doesn't show the attribute and only shows the message.
Why not use
validates :picture, presence: true
on your useritem model

Rails 4 Nested Resources, Forms, strong params

I am trying to create a workout tracker. I have these nested resources
Routes.rb
resources :days do
resources :workouts
resources :meals
end
My models look fine:
Workout.rb
class Workout < ActiveRecord::Base
has_many :exercises
belongs_to :day
end
Day.rb
class Day < ActiveRecord::Base
has_many :workouts
has_many :meals
accepts_nested_attributes_for :workouts, :allow_destroy => true
accepts_nested_attributes_for :meals, :allow_destroy => true
end
The issue lies when I try to create a new workout..
../views/workouts/_form.html.haml
= form_for([#day, #workout]), html: {class: 'form-horizontal'}) do |f|
= f.input :workout, label: "What did you work out", input_html: { class: "form-control"}
= f.input :mood, label: "How do you feel", input_html: { class: "form-control"}
= f.hidden_field :day_id, value: params[:day_id], input_html: { class: "form-control"}
= f.submit
I cant seem to save the :day_id the workout is associated with the workout though using strong params to receive them.
WorkoutsController.rb
private
def workout_params
params.require(:workout).permit(:day_id, :name, :mood)
end
def find_day
#day = Day.find(params[:day_id])
end
Instead what gets saved is a nil for :day_id
Rails Console:
Workout id: 11, name: "Hey", mood: "no", day_id: nil, created_at: "2014-12-19 14:53:29", updated_at: "2014-12-19 14:53:29"
HELP?
PS - i tried to do
= form_for([#day, #workout]), as: :foo, html: {class: 'form-horizontal'}) do |f|
= f.input :workout, label: "What did you work out", input_html: { class: "form-control"}
= f.input :mood, label: "How do you feel", input_html: { class: "form-control"}
= f.hidden_field :day_id, value: params[:day_id], input_html: { class: "form-control"}
= f.submit
and then
def workout_params
params.require(:foo).permit(:day_id, :name, :mood)
end
But it just kept saying the :foo params where empty
The way your routes are set up, I am assuming that the day_id is being passed as a url params:
/days/:day_id/workouts
If that is the case, then you do not need to worry about #day in the form, nor the day_id in the workout_params
Form:
= form_for #workout, html: {class: 'form-horizontal'}) do |f|
= f.input :workout, label: "What did you work out", input_html: { class: "form-control"}
= f.input :mood, label: "How do you feel", input_html: { class: "form-control"}
= f.submit
Controller:
def create
#workout = #day.workouts.new(workout_params)
....
end
private
def workout_params
params.require(:workout).permit(:name, :mood)
end
def find_day
#day = Day.find(params[:day_id])
end

Resources