OneZero
OneZero

Reputation: 11904

In model, when to use attr_accessor and when to use attr_accessible?

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

Answers (2)

Shanky Munjal
Shanky Munjal

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

Brad Werth
Brad Werth

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

Related Questions