0

User model:

class User < ActiveRecord::Base

attr_accessor :name, :email
has_secure_password
validates :password, presence: true, length: { minimum: 6 }

end

The problem is, in the Rails console, the attributes name, email, password, password_confirmation don't show up.

I suspect the first two are caused due to setting attr_accessor :name, :email and the latter two due to has_secure_password

But, when I call those attributes separately, they show up:

Loading development environment (Rails 4.2.0)
2.2.1 :001 > u = User.new(name: "asd", email: "aedede@aece.com", password: "qweasd", password_confirmation: "qweasd")
 => #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil, password_digest: "$2a$10$a98/zxfH0zaT0Hh.xalVPOxwbJiXAkH17BiRg.sV4hw..."> 
2.2.1 :002 > u
 => #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil, password_digest: "$2a$10$a98/zxfH0zaT0Hh.xalVPOxwbJiXAkH17BiRg.sV4hw..."> 
2.2.1 :003 > u.name
 => "asd" 
2.2.1 :004 > u.email
 => "aedede@aece.com" 
2.2.1 :005 > u.password
 => "qweasd" 
2.2.1 :009 > u.save
(0.2ms)  begin transaction
  User Exists (0.2ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('aedede@aece.com') LIMIT 1
  SQL (0.4ms)  INSERT INTO "users" ("password_digest", "created_at", "updated_at") VALUES (?, ?, ?)  [["password_digest", "$2a$10$a98/zxfH0zaT0Hh.xalVPOxwbJiXAkH17BiRg.sV4hwFXp2jUiTnm"], ["created_at", "2015-06-10 02:42:22.437148"], ["updated_at", "2015-06-10 02:42:22.437148"]]
   (130.8ms)  commit transaction
 => true 
2.2.1 :010 > u
 => #<User id: 3, name: nil, email: nil, created_at: "2015-06-10 02:42:22", updated_at: "2015-06-10 02:42:22", password_digest: "$2a$10$a98/zxfH0zaT0Hh.xalVPOxwbJiXAkH17BiRg.sV4hw..."> 
2.2.1 :011 > u.name
 => "asd"

I've checked everything thoroughly and can't find what's causing this, any insights to what's actually happening under the hood would be deeply appreciated.

Pre-alpha
  • 295
  • 3
  • 15

1 Answers1

-1

password is not a column in your database users, and neither it should be. It is just an attribute. If you have used has_secure_password, and you have - Rails will automatically take the password you specified, encrypt it, and store a password_digest in the database. There would be not password column in the database.

In Rails 4.2, you don't need to write attr_accessor with your column names in your model. If you have defined them in migration, Rails will automagically create getter/setter and a bunch of other helping methods for you. So, you model User should look like following in Rails 4.2:

class User < ActiveRecord::Base

  has_secure_password
  validates :password, presence: true, length: { minimum: 6 }
end
Arslan Ali
  • 17,418
  • 8
  • 58
  • 76
  • Ok thanks, that clears up the password, but what about the name and email? – Pre-alpha Jun 10 '15 at 07:00
  • Yes, they are the columns in the database. As you have seen it through `User.column_names`. In Rails 4.2, you do not need to write `attr_accessor :name, :email` in your Model; if you have written them in migration, Rails will automatically create methods for you. – Arslan Ali Jun 10 '15 at 07:02
  • attr_accessor is different than attr_accessible...we don't have to define attr_accessible..but we can define attr_accessor..:) – Vrushali Pawar Jun 10 '15 at 07:07
  • Yes, we can use `attr_accessor` but we do not need to use it with database column in our model class. And if we do, we won't be able to access other helper methods that Rails creates for use. For example, you won't be able to do `User.find_by_email` or `User.find_by_email` if you used `attr_accessor :name, :email`. – Arslan Ali Jun 10 '15 at 07:09
  • @test For more information, take a look at this answer: http://stackoverflow.com/questions/14401768/how-does-activerecord-define-methods-compared-to-attr-accessor/14452353#14452353 – Arslan Ali Jun 10 '15 at 07:09
  • **In Rails 4.2, you don't need to write attr_accessor with your column names in your model.** as you have mentioned I think that is for attr_accessible? – Vrushali Pawar Jun 10 '15 at 07:10
  • @test Yes, we don't need. And if we do, we won't be able to use the methods like `User.find_by_email`. Please take a look at the link in my last comment. – Arslan Ali Jun 10 '15 at 07:11
  • @test When you use `rails g scaffold User name:string email:string`, do you see those `attr_accessor` in your Model `User` class? – Arslan Ali Jun 10 '15 at 07:13
  • in rails version < 4 , the above command was creating `attr_accessible :name, :email` in model and not `attr_accessor :name, :email` – Vrushali Pawar Jun 10 '15 at 07:16
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/80134/discussion-between-arslan-ali-and-test). – Arslan Ali Jun 10 '15 at 07:17