Ruby on Rails attr_protected
У меня есть следующий код в моей модели пользователя:
attr_protected :email
Я пытаюсь создать новый пользовательский объект, но получаю ошибку, защищенную массовым назначением, со следующим кодом.
user = User.new(
:first_name => signup.first_name,
:last_name => signup.last_name,
:email => signup.email,
:birthday => signup.birthday,
:encrypted_password => signup.encrypted_password,
:salt => signup.salt
)
Кто-нибудь знает, как я могу обойти attr_protected, чтобы этот код работал и присвоить значение электронной почте?
Спасибо.
4 ответа
user = User.new(
:first_name => signup.first_name,
:last_name => signup.last_name,
:birthday => signup.birthday,
:encrypted_password => signup.encrypted_password,
:salt => signup.salt
)
user.email = signup.email
Я буквально сегодня написал камень, чтобы разобраться с этой проблемой. Я планирую добавить его на RubyGems.org позже на этой неделе после того, как я сделаю презентацию. Не стесняйтесь проверить код в то же время. http://github.com/beerlington/sudo_attributes
Используя гем, ваш код изменится на:
user = User.sudo_new(
:first_name => signup.first_name,
:last_name => signup.last_name,
:email => signup.email,
:birthday => signup.birthday,
:encrypted_password => signup.encrypted_password,
:salt => signup.salt
)
Вы также можете использовать sudo_create()
если вы хотите сохранить экземпляр
update_attributes теперь позволяет вам переопределить защиту, если вы знаете, что хеш безопасен, скажем, для внутреннего использования, где настраиваемые поля не приходят из контролируемого пользователем хеша.
user = User.new({
first_name: signup.first_name,
last_name: signup.last_name,
email: signup.email,
birthday: signup.birthday,
encrypted_password: signup.encrypted_password,
salt: signup.salt
}, {without_protection: true})
Вы также можете рассмотреть роли:
User.new(params, as: :admin)
Ядром защиты является self.attributes=, который, если вы используете self.send, может вызвать специальный скрытый параметр в конце, называемый guard_protected_attributes, как false.
Пример:
self.send(:attributes=, hash, false)
Это полностью пропустит функцию защиты. Он не работает с новым, но вы можете сначала создать объект, затем вызвать тот же метод и сохранить, не слишком больно, я думаю.