WARNING: Can't mass-assign protected attributes - ruby-on-rails-3

I get this error "WARNING: Can't mass-assign protected attributes: races_attributes"
, when following this http://railscasts.com/episodes/196-nested-model-form-part-1 on rails 3.
Where Races are a component of Events. This is my models/race.rb:
class Race < ActiveRecord::Base
belongs_to :event
attr_accessible :name, :unit
end
This is my models/event.rb:
class Event < ActiveRecord::Base
has_many :races, :dependent => :destroy
accepts_nested_attributes_for :races
attr_accessible :name, :date, :description, :location_name, :address_one, :address_two, :city, :state, :zip, :active, :races_attributes
end
Any Ideas?

Shorter than using attr_accessible, safer than using whitelist_attributes: attr_protected
Just indicate the protected attributes, and Rails will infer that all others can be mass-assigned:
class MyClass < ActiveRecord::Base
attr_protected :id
end
(I always have way more attributes that I want mass-assigned than the ones I want protected.)

attr_accessible specifies that you can not mass-assign attributes, using save method, for example. So, if you change an attribute that is not defined with attr_accessible, you will get a warning because it will not actually be saved in the database.

Related

Class with nested association to itself

I have a class with a nested association to itself:
class Location < ActiveRecord::Base
has_many :location_gateways
has_many :gateways, through: :location_gateways, class_name: "Location", :dependent => :destroy
accepts_nested_attributes_for :gateways, reject_if: :all_blank, allow_destroy: true
belongs_to :location, optional: true
end
The connecting model:
class LocationGateway < ActiveRecord::Base
belongs_to :location, :class_name => "Location"
belongs_to :gateway, :class_name => "Location"
end
Now I would like to make a form that can create a Location and some gateways but I get an Gateway must exist error when I submit it (the call to Location.new)
I'm assuming this is because the model Gateway doesn't exist. How can I make rails understand that it should create another Locationand not a Gateway?
Found no way around this error. I had to make a new class Gateway that inherits from Location and add a type to Locations (STI).

How do I write an Rspec test for an ActiveRecord polymorphic association

Has anyone found a way to write an rspec example for an ActiveRecord polymorphic association?
I'm used to using Thoughtbot's shoulda matches, but I think polymorphic's are beyond it's scope?
Just for clarity my models would have a similar pattern to this:
class Person < ActiveRecord::Base
attr_accessible :name
has_one :address, as: :location_data_source
accepts_nested_attributes_for :address
end
class Company < ActiveRecord::Base
attr_accessible :name
has_one :address, as: :location_data_source
accepts_nested_attributes_for :address
end
class Address < ActiveRecord::Base
attr_accessible :street, :city
belongs_to :location_data_source, polymorphic: true
end

Added two "belongs_to" to a Comment model but unable to get one of the associations

I am currently building very simple Comment system on Rails. The primary models are User, Albumpost, and Comment. Users can post Albumposts. For each Albumpost, Users can add Comments to the Albumpost. As a result, a Comment belongs to a User and belongs to an Albumpost.
The problem I'm having is that even with the proper associations in my models (see below), I can't get
#comment.user.name
when I'm trying to render the comments in the albumpost 'show' page (/views/albumposts/show.html.erb). When I go to the page, I can't get #comment.user.name (doesn't understand the association) and get a
"undefined method `name' for nil:NilClass"
Oddly I can get
#comment.albumpost.content
I've double-checked my models and also added the proper foreign keys to the models. Am I doing something wrong in the controllers?
Here are my models:
class Comment < ActiveRecord::Base
attr_accessible :body, :albumpost_id, :user_id
belongs_to :albumpost
belongs_to :user
end
class Albumpost < ActiveRecord::Base
attr_accessible :content
belongs_to :user
has_many :comments, dependent: :destroy
end
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation
has_many :albumposts, dependent: :destroy
has_many :comments, dependent: :destroy
end
Here are the relevant parts of my Albumpost and Comments controllers:
class AlbumpostsController < ApplicationController
def show
#albumpost = Albumpost.find(params[:id])
#comments = #albumpost.comments
#comment = Comment.new
#comment.albumpost_id = #albumpost.id
#comment.user_id = current_user.id
end
end
class CommentsController < ApplicationController
def create
albumpost_id = params[:comment].delete(:albumpost_id)
#comment = Comment.new(params[:comment])
#comment.albumpost_id = albumpost_id
#comment.user_id = current_user.id
#comment.save
redirect_to albumpost_path(#comment.albumpost)
end
end
I think you should prefer setting objects to relations instead of setting their ids. For example, you should do this:
#comment.user = current_user
instead of
#comment.user_id = current_user.id
ActiveRecord will take care of setting corresponding *_id fields. I'm not sure how it handles the reverse. (it should autoload though, if I understand correctly)

Rails, get object association when using build (object still not in database), the DRY

Im building a report system which uses a sort of meta question model. Questions are previusly saved in the database, and then depending of the type of report some questions are taken from the database.
Wanting to keep things DRY, i'm trying to figure out a way to pass the information of the Variable model to my report_header with no avail.
In the new action i have:
reportBody = #report_head.report_bodies.build(:variable_id => a.id)
#report_head.variables #modified, thx.
all i need is to pass the attributes from the Variable to report_head in a DRY way.
If you need to know my models:
class Variable < ActiveRecord::Base
attr_accessible :id,:break_point, :description, :name, :time_frequency, :v_type
has_many :report_bodies
has_many :report_heads, :through => :report_bodies
end
class ReportHead < ActiveRecord::Base
attr_accessible :email, :name , :report_bodies_attributes, :report_bodies, :variables_attributes
has_many :report_bodies
has_many :variables, :through => :report_bodies
accepts_nested_attributes_for :report_bodies
end
class ReportBody < ActiveRecord::Base
attr_accessible :report_head_id, :variable_value, :variable_id, :variables_attributes, :report_heads
belongs_to :report_head
belongs_to :variable
end
Update
I updated the model as suggested, and modified the way to call the variables. However im still confused about how to use it in the view, if i do something like:
<%= f.fields_for :variables do |variable| %>
<%= variable.text_field :name, :value => :name, :class => 'text_field' %>
<% end %>
it prints a string instead of the actual name.
You have define wrong name association, your association of ReportBody should be:
belongs_to :report_head
belongs_to :variable
This is not correct:
#report_head.report_bodies.build(:variable_id => a.id,:report_head_id =>#report_head.id)
chang it to:
#report_head.variables.build(:variable_id => a.id)
it's better, you don't have to set report_head_id. And this is wrong:
#report_head.report_bodies.variables
If you want to get all variables belong to #report_head, you just need using:
#report_head.variables

Cant mass-assign protected attributes issue

I know all the security reasons behind why mass-assigning is bad, what I cant figure out is why my app is trying to do a mass assign.
I am just trying to create a new record of my Section model and I am getting the "Can't mass-assign protected attributes" error. Below are the possible involved models. Can someone please explain to me how this is a mass-assigning? I am new to rails, so I could be missing something very simple.
class Section < ActiveRecord::Base
belongs_to :project
belongs_to :type, :foreign_key => 'type_id', :class_name => 'SectionType'
attr_accessor :order
end
class SectionType < ActiveRecord::Base
attr_accessible :name, :template
end
class Project < ActiveRecord::Base
has_many :sections
attr_accessible :description, :name, :short, :status, :subtitle, :version
def to_param
return name.gsub(/\s+/, '%20')
end
end
Any help would be greatly appreciated, I am new to rails and know this is probably a simple problem, but I have been trying to find an answer and can not.
If you're attempting to create a new Section object and that's failing, that'd be because you don't have any attributes listed as accessible inside that model. You will need to do that, using a similar call to attr_accessible as the one you have in your Project model already.