Rails 4 unpermitted params error - ruby-on-rails

I am receiving this error when a form submits:
Unpermitted parameters: postal_address_type_faos
I can confirm that the params come in ok but it looks like the postal_address_type_faos is being removed.
This is the params whitelist:
def paper_params
params.require(:paper).permit(:status, :signature_id, :name, :code,
:create_user_id, :update_user_id, :created_at, :updated_at,
phone_numbers_attributes: [:id, :phone_type_id, :area_code, :number, :extension, :create_user_id, :update_user_id, :created_at, :updated_at, :_destroy],
postal_addresses_attributes: [:id, :postal_address_type_id, :country_id, :line_1,:line_2, :line_3, :city, :territory_id, :postal_zip_code,
:address_note, :latitude, :longitude,
:_destroy, :address_verification_status_id, :comment,
postal_address_type_faos_attributes: [:id, :postal_address_id, :postal_address_type_id, :fao, :create_user_id, :update_user_id, :created_at, :updated_at, :_destroy]])
end
Models:
class Paper < ActiveRecord::Base
has_many :paper_postal_addresses
has_many :postal_addresses, through: :paper_postal_addresses
has_many :postal_address_type_faos, through: :postal_addresses
accepts_nested_attributes_for :postal_addresses
accepts_nested_attributes_for :postal_address_type_faos
has_many :phone_number_papers
has_many :phone_numbers, through: :phone_number_papers
accepts_nested_attributes_for :phone_numbers, allow_destroy: true
class PaperPostalAddress < ActiveRecord::Base
belongs_to :paper
belongs_to :postal_address
has_many :postal_address_type_faos, through: :postal_address
class PostalAddress < ActiveRecord::Base
has_many :postal_address_type_faos
has_many :postal_address_types, :through => :postal_address_type_faos
has_many :paper_postal_addresses
has_many :papers, through: :paper_postal_addresses
class PostalAddressTypeFao < ActiveRecord::Base
belongs_to :postal_address_type
belongs_to :postal_address
has_many :paper_postal_addresses, through: :postal_address
class PostalAddressType < ActiveRecord::Base
has_many :postal_address_type_faos
has_many :postal_addresses, through: :postal_address_type_faos
View code from the address partial is something like this
<%= f.fields_for :postal_addresses do |address|%>
//some address stuff here
//then do address fao type stuff (index is populated but not shown here)
<%= f.fields_for :postal_address_type_faos, #paper.postal_addresses[address.index].postal_address_type_faos[index] do |fa| %>
<%= fa.check_box :postal_address_type_id, label: fa.object.postal_address_type.name %>
<%= fa.text_field :fao, label: fa.object.fao %>
<% end %>
<% end %>
Params coming back as:
{"utf8"=>"✓", "authenticity_token"=>"R8ukkukuykuk",
"paper"=>{"carrier_id"=>"", "name"=>"", "status"=>"Active","digital_id"=>"1","signature_id"=>"1", "phone_numbers_attributes"=>{"0"=>{"create_user_id"=>"1568", "phone_type_id"=>"2", "country_phone_code_id"=>"2", "area_code"=>"",
"number"=>"", "extension"=>""}}, "postal_addresses_attributes"=>{"0"=>{"country_id"=>"", "line_1"=>"", "line_2"=>"", "line_3"=>"", "city"=>"", "territory_id"=>"", "postal_zip_code"=>"", "subterritory"=>"", "comment"=>""},
"1"=>{"country_id"=>"", "line_1"=>"", "line_2"=>"", "line_3"=>"", "city"=>"", "territory_id"=>"", "postal_zip_code"=>"", "subterritory"=>"", "comment"=>""},
"2"=>{"country_id"=>"", "line_1"=>"", "line_2"=>"", "line_3"=>"", "city"=>"", "territory_id"=>"", "postal_zip_code"=>"", "subterritory"=>"", "comment"=>""}},
"postal_address_type_faos_attributes"=>{"0"=>{"postal_address_type_id"=>"1", "attention"=>""}, "1"=>{"postal_address_type_id"=>"0", "fao"=>""}, "2"=>{"postal_address_type_id"=>"0", "fao"=>""}, "3"=>{"postal_address_type_id"=>"0",
"fao"=>""}, "4"=>{"postal_address_type_id"=>"0", "fao"=>""}}}, "area_code_required"=>"", "formaction"=>"add_address", "action"=>"create",
"controller"=>"papers"}

Just change view code from
<%= f.fields_for :postal_address_type_faos, #paper.postal_addresses[address.index].postal_address_type_faos[index] do |fa| %>
to
<%= address.fields_for :postal_address_type_faos, #paper.postal_addresses[address.index].postal_address_type_faos[index] do |fa| %>

Related

Rails nested form for complex associations

Problems:
=rfv.text_area :value render void textarea in edit action (but in db this field has value)
can't get array of role_field_values[] in params
My models and associations:
class Participant < ActiveRecord::Base
belongs_to :role
has_many :role_field_values, dependent: :destroy
accepts_nested_attributes_for :role_field_values
end
class Role < ActiveRecord::Base
has_many :role_fields
has_one :participant
end
class RoleField < ActiveRecord::Base
belongs_to :role
has_many :role_field_values
end
class RoleFieldValue < ActiveRecord::Base
belongs_to :participant
belongs_to :role_field
end
My form edit.slim:
=simple_form_for [#project.becomes(Project), #participant] do |f|
=f.error_notification
h4 =#participant.profile.fio
.form-inline
=f.association :role, remote: true
=f.input :status
#role-fields
=fields_for :role_fields_values do |rfv|
-#participant.role.role_fields.each do |role_field|
.form-group
=rfv.hidden_field :role_field_id, value: role_field.id
br
=rfv.label role_field.name
=rfv.text_area :value, class: 'form-control'
.form-actions
= f.button :submit
Use f.fields_for instead of fields_for

Rails: Use a collection of checkboxes to add/remove entries on a different table with ActiveRecord

I have three objects: Contact, Sector, and Contact_sector.
Contact contains an id and some other irrelevant (non-reference) columns
Sector contains an id and sector column with ~10 editable entries
Contact_sector has a contact_id reference and a sector_id reference. In my mind I imagine that every sector that applies to some contact can be found here, and if a sector is un-applied it is removed from here.
I want to have a collection of checkboxes in the contact _form formed from list of entries in :sectors, but updating the form with certain boxes ticked adds/removes entries from :contact_sectors.
Where am I going wrong?
UPDATED: Fixed strong_params to permit sectors, now I am unable to find the sectors by id ActiveRecord::RecordNotFound (Couldn't find Sector with ID=["1", ""] for Contact with ID=1)
Models:
class Contact < ActiveRecord::Base
has_many :contact_sectors
has_many :sectors, through: :contact_sectors
accepts_nested_attributes_for :contact_sectors, :reject_if => :all_blank, :allow_destroy => true
accepts_nested_attributes_for :sectors, :reject_if => :all_blank, :allow_destroy => true
end
class Sector < ActiveRecord::Base
has_many :contact_sectors
has_many :contacts, through: :contact_sectors
def name_with_initial
"#{sector}"
end
end
class ContactSector < ActiveRecord::Base
belongs_to :contact
belongs_to :sector
end
View:
<%= f.fields_for(:sectors) do |s| %>
<%= s.collection_check_boxes :id, Sector.all,
:id, :name_with_initial,
{ prompt: true }, { class: 'form-control' } %>
<% end %>
Controller
def edit
#contact.sectors.build
end
def contact_params
#Not sure if I need something like this or not
params['contact']['sectors'] = params['contact']['sectors']['id'].split(',')
params.require(:contact).permit(:firstname, :lastname,
contact_sectors_attributes: [:id],
sectors_attributes: [:_destroy, {:id => []}])
end
Instead of creating the join model explicitly you can just declare the relationship as has_many through: and let ActiveRecord handle the join model:
class Contact < ActiveRecord::Base
has_many :contact_sectors
has_many :sectors, through: :contact_sectors
accepts_nested_attributes_for :sector,
reject_if: :all_blank, allow_destroy: true
end
class Sector < ActiveRecord::Base
has_many :contact_sectors
has_many :contacts, through: :contact_sectors
end
class ContactSector < ActiveRecord::Base
belongs_to :contact
belongs_to :sector
end
<%= form_for(#contact) do |f| %>
<%= f.fields_for(:sectors) do |s| %>
<%= s.collection_check_boxes :id, Sector.all,
:id, :name_with_initial,
{ prompt: true }, { class: 'form-control' } %>
<% end %>
<% end %>
models
class Contact < ActiveRecord::Base
has_many :sectors, through: :contact_sectors
has_many :contact_sectors
accepts_nested_attributes_for :sectors
end
class Sector < ActiveRecord::Base
has_many :contacts, :through => :contact_sectors
has_many :contact_sectors
end
class ContactSector < ActiveRecord::Base
belongs_to :contact
belongs_to :sector
end
view
<%= form_for(#contact) do |f| %>
<% Sector.all.each do |sector| %>
<%= check_box_tag "contact[sector_ids][]", sector.id, f.object.sectors.include?(sector) %>
<%= sector.sector %>
<% end %>
<% end %>
controller
def update
#To make sure it updates when no boxes are ticked
#contact.attributes = {'sector_ids' => []}.merge(params[:contact] || {})
end
def contact_params
params.require(:contact).permit(:firstname, :lastname, sector_ids: [])
end
Recommended reading:
http://millarian.com/rails/quick-tip-has_many-through-checkboxes/
Rails 4 Form: has_many through: checkboxes

accepts_nested_attributes_for with belongs_to polymorphic devise

I have 3 models and this associations for them
class User < ActiveRecord::Base
# devise modules here
attr_accessible :email, :password, :password_confirmation, :remember_me, :rolable_id, :rolable_type
belongs_to :rolable, :polymorphic => true
end
class Player < ActiveRecord::Base
attr_accessible :age, :name, :position
has_one :user, :as => :rolable
end
class Manager < ActiveRecord::Base
attr_accessible :age, :name
has_one :user, :as => :rolable
end
I'm out of the box from rails way to put accepts_nested_attributes_for :rolable on user model and In this accepts_nested_attributes_for with belongs_to polymorphic question I found some solutions for it but all solution not works for me. All solutions, always the same error when I try to create a user
Processing by RegistrationsController#create as HTML
Parameters: {"utf8"=>"V", "authenticity_token"=>"WKCniJza+PS5umMWCqvxFCZaRVQMPZBT4nU2fl994cU=", "user"=>{"email"=>"john#email.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "rolable_type"=>"manager", "rolable"=>{"name"=>"john", "age"=>"24"}}, "commit"=>"Sign up"}
Completed 500 Internal Server Error in 143.0ms
NoMethodError (undefined method `primary_key' for ActiveSupport::HashWithIndifferentAccess:Class):
app/controllers/registrations_controller.rb:13:in `new'
app/controllers/registrations_controller.rb:13:in `create'
My mistake, I'm use nested form
<%= f.fields_for :rolable do |rf| %>
....
<% end %>
change to
<%= f.fields_for :rolable_attributes do |rf| %>
....
<% end %>
for polymorphic association you have to maintain generic model Roll like
class User < ActiveRecord::Base
# devise modules here
attr_accessible :email, :password, :password_confirmation, :remember_me
has_many :rolls, :as => :rolable
end
class Player < ActiveRecord::Base
attr_accessible :age, :name, :position
has_many :rolls, :as => :rolable
end
class Manager < ActiveRecord::Base
attr_accessible :age, :name
has_many :rolls, :as => :rolable
end
class Roll < ActiveRecord::Base
attr_accessible :rolable_id, :rolable_type
belongs_to :rolable, :polymorphic=> true
end

nested_attributes with simple_field_for getting unpermitted parameters error rails

I have models
class Profile < ActiveRecord::Base
belongs_to :user
has_many :user_interests
has_many :interests, :through => :user_interests
accepts_nested_attributes_for :user_interests
end
class UserInterest < ActiveRecord::Base
belongs_to :profile
belongs_to :interest
end
class Interest < ActiveRecord::Base
has_many :user_interests
has_many :profiles, :through => :user_interests
end
controller
private
def profile_params
params.require(:profile).permit(:first_name, :last_name, :date_of_birth, user_interests_attributes: {:interest => []})
end
view
=#"http://stackoverflow.com/questions/18428871/multi-column-forms-with-fieldsets"
= simple_form_for(#profile, html: {class: 'form-horizontal'}) do |f|
.well.well-lg
%fieldset
%legend Personal Information
.row
.col-sm-4
.form-group
= f.input :first_name, label: 'First Name*'
= f.hint 'No special characters, please!'
.col-sm-4
.form-group
= f.input :last_name, label: 'First Name*'
= f.hint 'No special characters, please!'
.row
.col-sm-4
.form-group
= f.input :date_of_birth, as: :string, 'data-behaviour'=>'datepicker'
%legend Other Information
.row
.col-sm-4
.form-group
= f.simple_fields_for :user_interests, UserInterest.new do |s|
= s.collection_select(:interest, Interest.all, :id, :name,{},{:multiple=>true})
= f.hint 'Please use Ctrl key on your keyboard to select multiple items'
.row
= f.submit
But getting error unpermitted parameters
profile_params
Unpermitted parameters: interest
=> {"first_name"=>"", "last_name"=>"", "date_of_birth"=>"", "user_interests_attributes"=>{"0"=>{}}}
where my params are:
params
=> {"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"7/7sKljbi88cmUOen/WFWzhzV6exE8I8fBnNMA5EELw=",
"profile"=> {"first_name"=>"", "last_name"=>"",
"date_of_birth"=>"",
"user_interests_attributes"=>{"0"=>{"interest"=>"test"}}},
"commit"=>"Update Profile", "action"=>"update",
"controller"=>"profiles", "id"=>"1"}
Please correct me where I am wrong
You forgot to add accepts_nested_attributes_for :interest on UserInterest.
class Profile < ActiveRecord::Base
belongs_to :user
has_many :user_interests
has_many :interests, :through => :user_interests
accepts_nested_attributes_for :user_interests
end
class UserInterest < ActiveRecord::Base
belongs_to :profile
belongs_to :interest
accepts_nested_attributes_for :interest
end
class Interest < ActiveRecord::Base
has_many :user_interests
has_many :profiles, :through => :user_interests
end
You might have to define interest as a valid parameter on strong_parameters definition in your controller.

Rails 3 has_many :through Form

Can't figure out why this is not working. First time using :has_many => :through
Keep getting uninitialized constant User::Employmentship
class User < ActiveRecord::Base
has_many :employmentships
has_many :companies, :through => :employmentships
accepts_nested_attributes_for :employmentships, :allow_destroy => true, :reject_if => proc { |obj| obj.blank? }
attr_accessible :email, :password, :password_confirmation, :firstname, :lastname, :username, :role, :company_ids
end
class Company < ActiveRecord::Base
has_many :employmentships
has_many :users, :through => :employmentships
end
/views/users/_form.html.erb
<p>
<%= for company in Company.all do %>
<%= check_box_tag "user[company_ids][]", company.id, #user.companies.include?(company) %>
<%= company.name%>
<% end %>
</p>
EDIT - If I change #user.companies.include?(company) to false i get the form, but nothing updates.
EDIT 2 -
class Employmentship < ActiveRecord::Base
belongs_to :company
belongs_to :user
attr_accessor :company_id, :user_id
end
Where is you employmentship model? has_many_through is for going through another model.

Resources