Reputation: 11904
attr_accessible
is used by default, but in #250 in railscasts, it uses attr_accessor
so I'm confused.
In Authentication from Scratch
tutorial, the code is
class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation
attr_accessor :password
...
end
But in the database, it actually stores only password_hash and password_salt, which do not match our attr_accessible and attr_accessor, can anyone explain this a little bit for me?
Upvotes: 2
Views: 210
Reputation: 671
attr_accessor is for creating virtual attributes
attr_accessible is for mass assignment
According to tutorial
attr_accessor :password (because password field is not in database)
attr_accessible :password, :password_confirmation (because of mass assignment)
password_salt and password_hash are in only before_save callback so there is no need to write these in attr_accessible or attr_accessor
Upvotes: 0
Reputation: 17647
attr_accessible
specifies a white list of model attributes that can be set via mass-assignment. (source)
attr_accessor
defines a named attribute for this module, where the name is symbol.id2name, creating an instance variable (@name) and a corresponding access method to read it. Also creates a method called name= to set the attribute. (source)
So, basically, if you need a non-database-backed attribute, use attr_accessible
. If you need to mass assign an attribute, whether or not it is backed by the db, use attr_accessible
. If you need to mass assign a non-database-backed attibute, you would use both.
This all makes perfect sense in the context of your updated question. In a migration, the password_hash
field is added as a db-backed attribute to the model. Then in the code, password
(and its confirmation) are added as non-database backed attributes. The line before_save :encrypt_password
calls the encrypt_password
method before the model is saved. In that method, the database-backed attribute is derived from the non-database backed attributes. The reason you don't need attr_accessor :password_hash
is because it is never mass-assigned (like password
), but rather explicitly set. Make sense?
Upvotes: 2