Консоль Rails игнорирует атрибуты, установленные с помощью attr_accessor, а has_secure_password заставляет игнорировать пароль и password_confirmation

Модель пользователя:

class User < ActiveRecord::Base

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

end

Проблема в том, что в консоли Rails атрибуты name, email, password, password_confirmation не отображаются.

Я подозреваю, что первые два вызваны настройкой attr_accessor :name, :email, а последние два - has_secure_password

Но когда я вызываю эти атрибуты по отдельности, они появляются:

Loading development environment (Rails 4.2.0)
2.2.1 :001 > u = User.new(name: "asd", email: "[email protected]", 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
 => "[email protected]" 
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('[email protected]') 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"

Я все тщательно проверил и не могу найти, что вызывает это, я буду очень признателен за любое понимание того, что на самом деле происходит под капотом.


person Pre-alpha    schedule 10.06.2015    source источник
comment
имя и адрес электронной почты не являются столбцами пользовательской таблицы?   -  person Vrushali Pawar    schedule 10.06.2015
comment
как мне проверить, есть ли они?   -  person Pre-alpha    schedule 10.06.2015
comment
User.column_names в консоли рельсов   -  person Vrushali Pawar    schedule 10.06.2015
comment
2.2.1: 012 ›User.column_names =› [id, name, email, created_at, updated_at, password_digest]   -  person Pre-alpha    schedule 10.06.2015
comment
удалить имя attr_accessor, адрес электронной почты из user.rb, а затем попытаться создать экземпляр объекта и проверить, видны ли они?   -  person Vrushali Pawar    schedule 10.06.2015
comment
это уже сделано, они видны. Вот почему я спрашиваю, почему это вызывает attr_accessor?   -  person Pre-alpha    schedule 10.06.2015
comment
посмотрите мое объяснение использования attr_accessor для столбцов db в stackoverflow.com/questions/30683662/   -  person jvnill    schedule 10.06.2015


Ответы (1)


password не является столбцом в вашей базе данных users, и не должно быть. Это просто атрибут. Если вы использовали has_secure_password, а у вас есть - Rails автоматически возьмет указанный вами password, зашифрует его и сохранит password_digest в базе данных. В базе данных не будет столбца password.

В Rails 4.2 вам не нужно писать attr_accessor с именами столбцов в вашей модели. Если вы определили их при миграции, Rails автоматически создаст для вас геттер / сеттер и множество других вспомогательных методов. Итак, ваша модель User в Rails 4.2 должна выглядеть следующим образом:

class User < ActiveRecord::Base

  has_secure_password
  validates :password, presence: true, length: { minimum: 6 }
end
person Arslan Ali    schedule 10.06.2015
comment
Хорошо, спасибо, это проясняет пароль, но как насчет имени и адреса электронной почты? - person Pre-alpha; 10.06.2015
comment
Да, это столбцы в базе данных. Как вы видели это через User.column_names. В Rails 4.2 вам не нужно писать attr_accessor :name, :email в вашей модели; если вы написали их при миграции, Rails автоматически создаст для вас методы. - person Arslan Ali; 10.06.2015
comment
attr_accessor отличается от attr_accessible ... нам не нужно определять attr_accessible .. но мы можем определить attr_accessor .. :) - person Vrushali Pawar; 10.06.2015
comment
Да, мы можем использовать attr_accessor, но нам не нужно использовать его со столбцом базы данных в нашем классе модели. И если мы это сделаем, мы не сможем получить доступ к другим вспомогательным методам, которые Rails создает для использования. Например, вы не сможете делать User.find_by_email или User.find_by_email, если использовали attr_accessor :name, :email. - person Arslan Ali; 10.06.2015
comment
@test Для получения дополнительной информации взгляните на этот ответ: stackoverflow.com/questions/14401768/ - person Arslan Ali; 10.06.2015
comment
В Rails 4.2 вам не нужно писать attr_accessor с именами столбцов в вашей модели. как вы упомянули, я думаю, что это для attr_accessible? - person Vrushali Pawar; 10.06.2015
comment
@test Да, нам не нужно. И если мы это сделаем, мы не сможем использовать такие методы, как User.find_by_email. Пожалуйста, взгляните на ссылку в моем последнем комментарии. - person Arslan Ali; 10.06.2015
comment
@test Когда вы используете rails g scaffold User name:string email:string, видите ли вы эти attr_accessor в вашем классе Model User? - person Arslan Ali; 10.06.2015
comment
в версии rails ‹4 указанная выше команда создавала attr_accessible :name, :email в модели, а не attr_accessor :name, :email - person Vrushali Pawar; 10.06.2015
comment
Позвольте нам продолжить это обсуждение в чате. - person Arslan Ali; 10.06.2015