Thanks a lot, I like the simpler way you wrote out.
My question is, though, is that method vulnerable to mass-assignment
attacks? I know that if it were attr_accessible, a user would be able to
pass in a value for :signing_up and avoid having their data validated,
but I don't know whether the same is true for attr_accessor.
No, I think they don't work together, so just don't list :signing_up
in the accesible attributes list.
It is true that you cannot use both attr_accessible and attr_protected
in the same model. Rails will throw a runtime error if both are
specified on one model.
Ok, I've done some more reading and I think that I have this down now.
Somebody tell me if I'm on the right/wrong path.
attr_accessible lists attributes that are open to mass-assignment. So,
for security reasons, we shouldn't allow anything in attr_accessible
that we wouldn't let the user define themselves.
Active Record automatically creates setter/getter methods for columns in
databases - since my users table has a "name" column, for example, I can
use @user.name in my models/views/controllers and it'll just work.
However, when I want to use a virtual attribute (something that isn't
persisted in the database but that I still want to manipulate in Rails,
like @user.signing_up), ActiveRecord can't do that for me, and I have to
make setter/getter methods for that myself. I can make those with
attr_accessor, but they won't be mass-assignable, and so they won't be
vulnerable to mass-assignment attacks.
Finally, since the whitelist approach to security is better than the
blacklist approach, attr_protected should just be ignored.
1. Mass assignment doesn't care if the attributes are genreated by
ActiveRecord, defined using attr-accessor, or implemented explicitly.
It just doesn't allow some attributes to be mass assigned, so if
the :secret is protected then
user.attributes = {:secret => ...}
user.update_attributes(:secret => ...)
User.create(:secret => ...)
won't work, but
user.secret = ...
will work always for protected & for not-protected attributes.
attr_accesseble & attr_protected can be used interchangeably, just use
the one you like more, eg when User has 3 attributes: name, age &
salary, then:
attr_accessible :name, :age
is the same as
attr_protected :salary
In both case name & age will be accessible and salary will be
protected.