Есть ли способ обойти защиту массового присваивания? - PullRequest
23 голосов
/ 14 апреля 2011

У меня есть приложение Rails 3, которое JSON кодирует объекты, чтобы хранить их в хранилище ключей / значений Redis.

Когда я получаю объекты, я пытаюсь декодировать JSON и создавать их из данных следующим образом:

def decode(json)
  self.new(ActiveSupport::JSON.decode(json)["#{self.name.downcase}"])
end

Проблема в том, что для этого требуется массовое присвоение, которое запрещено (по уважительной причине, как мне сказали!) Для атрибутов, для которых я не дал атрибута attr_writer.

Есть ли способ обойти защиту массового назначения только для этой операции?

Ответы [ 3 ]

85 голосов
/ 21 августа 2012

assign_attributes с without_protection: true кажется менее навязчивым:

user = User.new
user.assign_attributes({ :name => 'Josh', :is_admin => true }, :without_protection => true)
user.name       # => "Josh"
user.is_admin?  # => true

@ tovodeverett, упомянутый в комментарии, вы также можете использовать его с new, например, в 1 строке

user = User.new({ :name => 'Josh', :is_admin => true }, :without_protection => true)
6 голосов
/ 14 апреля 2011

РЕДАКТИРОВАТЬ: kizzx2's Ответ является гораздо лучшим решением.

Вроде хак, но ...

self.new do |n|
  n.send "attributes=", JSON.decode( json )["#{self.name.downcase}"], false
end

Это вызывает атрибуты = передача false для параметра guard_protected_attributes, который пропустит любые проверки массовых назначений.

4 голосов
/ 09 ноября 2012

Вы также можете создать пользователя, который не выполняет массовое назначение.

User.create do |user|
  user.name = "Josh"
end

Возможно, вы захотите поместить это в метод.

...