how to avoid mass assignment error with has_many :through relationship - ruby-on-rails

I am trying to do an update_attributes of a nested model and keep running into a mass assignment error. Here are my models:
class Lineup < ActiveRecord::Base
belongs_to :user
has_many :piece_lineups
has_many :pieces, through: :piece_lineups
accepts_nested_attributes_for :piece_lineups
end
class Piece < ActiveRecord::Base
attr_accessible :cost, :description, :name, :category
has_many :piece_lineups
has_many :lineups, through: :piece_lineups
end
class PieceLineup < ActiveRecord::Base
attr_accessible :piece
belongs_to :piece
belongs_to :lineup
end
User has_one lineup by the way. So I thought that by adding accepts_nested_attributes_for to the lineup model that it would work but it is not. Here's my form:
- #lineup.piece_lineups.build(:piece => piece)
= form_for(#lineup) do |f|
= f.fields_for :piece_lineups do |piece_lineup|
= piece_lineup.hidden_field(:piece_id, :value => piece.id)
= f.submit
and my Lineup controller action:
def update
#lineup = current_user.lineup
#lineup.update_attributes(params[:lineup])
and finally, the error:
Can't mass-assign protected attributes: piece_lineups_attributes
What am i missing here? Thanks!

accepts_nested_attributes_for creates an attribute writer -- in your case, piece_lineups_attributes= -- for passing attributes to another model. So, you need to add attr_accessible :piece_lineups_attributes to your Lineup model to make it mass-assignable.
UPDATE
There is a better way of going about this.
If you add attr_accessible :piece_ids to your Lineup model, then change your view to
= form_for(#lineup) do |f|
= f.hidden_field(:piece_ids, :value => piece.id)
= f.submit
You don't need nested attributes at all.

Mass Assignment usually means passing attributes into the call that creates an object as part of an attributes hash. So add piece_lineup's fields to your list of attr_accessors for that model, OR try this:
#lineup = current_user.lineup
#lineup.piece_id = params[:piece_id]
#lineup.save
Also see:
http://api.rubyonrails.org/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html

Related

How to implement a many-to-many in ActiveAdmin?

There a many-to-many:
class Employee < ActiveRecord::Base
has_many :employees_and_positions
has_many :employees_positions, through: :employees_and_positions
end
class EmployeesAndPosition < ActiveRecord::Base
belongs_to :employee
belongs_to :employees_position
end
class EmployeesPosition < ActiveRecord::Base
has_many :employees_and_positions
has_many :employees, through: :employees_and_positions
end
How to implement a choice (check_boxes) positions in the form when adding an employee?
I wrote this variant:
f.inputs 'Communications' do
f.input :employees_positions, as: :check_boxes
end
It displays a list of positions in the form, but does not save nothing to the table (employees_and_positions).
How to fix?
Suppose you have an employee, you can reference the ids of the employees_positions association by using employee.employees_position_ids. Accordingly, you can mass assign pre-existing EmployeesPosition objects using a check_box for each EmployeesPosition, but you need to use the employee_position_ids attribute"
= f.input :employee_position_ids, as: :check_boxes, collection: EmployeesPosition.all
Also, make sure you've whitelisted the employee_position_ids param in your active admin resource:
ActiveAdmin.register Employee do
permit_params employee_position_ids: []
end
http://activeadmin.info/docs/2-resource-customization.html

Rails 4 strong parameters does not work for a polymorphic association

I have set a polymorphic association and added a nested form in the view. Im trying to create the main record and the association at the same time. The main record gets created but the association won't.
Here are the two models in question :
class UnRegistered < ActiveRecord::Base
has_one :vehicle, as: :detailable, dependent: :destroy
belongs_to :dealer
class Vehicle < ActiveRecord::Base
belongs_to :purchase_details, polymorphic: true
belongs_to :brand
belongs_to :model
belongs_to :color
belongs_to :customer
Here's the form definitions :
<%= form_for(#un_registered, url: panel_un_registereds_path, remote: true) do |f| %>
<%= f.fields_for :vehicle do |f_vehicle| %>
Here's a sample params set I get :
{"utf8"=>"✓", "un_registered"=>{"vehicle"=>{"brand_id"=>"", "model_id"=>"", "year"=>"", "engine_number"=>"gdfg", "chassis_number"=>"", "color"=>"", "options"=>""}, "original_price"=>"", "insurance"=>"", "freight"=>"", "tt"=>"", "tt_date"=>"", "duty"=>"", "clearance_fee"=>"", "other_expenses"=>"", "dealer_id"=>"", "landing_date"=>"", "loading_date"=>""}, "controller"=>"panel/un_registereds", "action"=>"create"}
Here's the controller actions :
def create
#un_registered = UnRegistered.create(un_registered_params)
end
def un_registered_params
params.require(:un_registered).permit(:original_price, :insurance, :freight, :tt, :tt_date, :duty, :clearance_fee, :other_expenses, :loading_date, :landing_date, :dealer_id, vehicle_attributes: [:id, :brand_id, :model_id, :engine_number, :chassis_number, :color_id, :year, :options, :selling_price, :customer_id, :purchase_date, :_destroy])
end
Full form code :
https://gist.github.com/THPubs/9665e0e5594e15fcc76a
New method :
def new
#un_registered = UnRegistered.new
end
Your form is fine. You just need to add below changes.
In your un_registered.rb model
class UnRegistered < ActiveRecord::Base
has_one :vehicle, as: :detailable, dependent: :destroy
belongs_to :dealer
accepts_nested_attributes_for :vehicle #this one
end
And in your controller,
def new
#un_registered = UnRegistered.new
#un_registered.build_vehicle #this one
end

Polymorphic association with has_one, can't create through association

I've got a polymorphic association with a has_one and it gives me an error when trying to create through association.
class User < ActiveRecord::Base
belongs_to :userable, polymorphic: true
end
class Student < ActiveRecord::Base
attr_accessible :gender, :description, :dob
has_one :user, :as => :userable
end
If I try to do:
s = Student.new
s.user.create
I get and error Undefined method create for 'nil'
But! If i change the association to has_many users then I can now preform the same lines above.
Can anyone explain why this is happening? Thanks!
The problem is that user is nil since you haven't assigned a value to it.
You should use something like:
s.build_user(...)
or
s.create_user(...)

Adding many models to another model

I'm currently working on a small project using Ruby On Rails 3.2 to create a database that contains several unique Models. Each Model has many Elements and each Element has the potential to belong to many Models. I have been able to set up the models in the following manner:
class Model < ActiveRecord::Base
has_many :model_elements
has_many :elements, :through => :model_elements
attr_accessible :elements, :name, :notes, :ref
end
class Element < ActiveRecord::Base
has_many :model_elements
has_many :models, :through => :model_elements
attr_accessible :elementType, :name, :notes, :ref
validates_presence_of :name
end
class ModelElement < ActiveRecord::Base
belongs_to :Model
belongs_to :element
attr_accessible :model_id, :created_at, :element_id
end
My question is how do I add multiple Elements to a single Model? I've tried to find some documentation but I can't find anything. Currently I'm trying to do the following:
#model.elements = #element
Where #element is a predefined element however it's throwing the following error:
undefined method `each' for #<Element:0x007ff803066500>
Any help would be greatly appreciated.
Try
#model.elements << #element
collection.create(attributes = {})
Returns a new object of the collection type that has been instantiated with attributes, linked to this object through the join table, and that has already been saved.
#model.elements.create(:name => "example")
Amar's answer is correct. If you wanted you can simplify your models further by using the has_and_belongs_to_many association.
class Model < ActiveRecord::Base
has_and_belongs_to_many :elements, :join_table => :model_elements
end
class Element < ActiveRecord::Base
has_and_belongs_to_many :models, :join_table => :model_elements
end
#model.elements << #element

Rails 3.2 double nested form and posting from child (Mongoid)

Having trouble posting from a child to a parent's other child:
Can this be done like I want, post from the child (Order) to the Parent's (User's) other child (Customer) or do you have to go at this from some other angle?
I have 3 Models:
class User
has_many :orders
has_one :customer, dependent: :destroy
accepts_nested_attributes_for :customer
class Order
belongs_to :user
belongs_to :project
class Customer
belongs_to :user
I've tried accepts_nested_attributes_for :orders from the user, I've also tried accepts_nested_attributes_for :user from the order
neither seem to work,
Hers my form:
= form_for #order do |f|
= f.hidden_field :user_id
= f.fields_for :user do |user|
= user.fields_for :customer do |customer|
= customer.hidden_field :customer_attribute
I am not sure this is possible. Anyway you certainly forgot to add
accepts_nested_attributes_for :user
in your Order class.

Resources