2014-03-13 5 views
0

Обычно, когда мы создаем модель, скажем User, ее атрибуты соответствуют полям базы данных. Например, если в моей соответствующей таблице базы данных users_development есть поля name и score, то при создании экземпляра класса User просто введите user = User.create(:name => "MyName", :score => 85).Devise and User.create

Теперь Разрабатывает создал миграционный файл, включая полей email и encrypted_password, но я не могу видеть поле password (что вполне логично с точки зрения безопасности).

При просмотре сообщений форума я видел много примеров, таких как User.create(:email =>"[email protected]", :password => "foo"). Итак, откуда появился password? Это не поле таблицы users_development. Что происходит за сценой? Я просмотрел документацию по адресу http://rubydoc.info/github/plataformatec/devise/master/Devise, но не нашел никаких объяснений.

ответ

3

User.create(:email => "[email protected]", :password => "foo") напрямую не создает запись базы данных с этими точными полями. Скорее, для каждой пары в хэшах параметров используется public_send("#{k}=", v). Так что на самом деле, он делает что-то вроде этого внутренне:

user = User.new 
user.email = "[email protected]" 
user.password = "foo" 
user.save 

Даже если вы не имеете поле в password базы данных, Разрабатывают-х DatabaseAuthenticatable module adds a password= method, который обновляет encrypted_password поле:

def password=(new_password) 
    @password = new_password 
    self.encrypted_password = password_digest(@password) if @password.present? 
end 
+0

спасибо! Это было полезно. – fade2black

+0

Это не документировано. Наверное, мне придется копаться в исходном коде, чтобы лучше понять Devise. В любом случае, это будет хорошее упражнение :-) – fade2black

2

This method из DEViSE исходного кода делает трюк:

# Generates password encryption based on the given value. 
def password=(new_password) 
    @password = new_password 
    self.encrypted_password = password_digest(@password) if @password.present? 
end 

При вызове create, update attributes, build, etc, rails будет пытаться вызвать для каждого поля метод field=, поэтому, когда вы проходите :password => 'foo' к create он будет делать что-то вроде:

user = User.new 
user.password = 'foo' 
user.save 

Вот этот метод позволяет строить модели с unhashed пароля, но хранить хэш пароля в базы данных.

+0

Большое спасибо! Это было полезно. – fade2black

Смежные вопросы