В чем разница между attr_accessible (* attributes) и attr_protected (* attributes)?

В чем разница между attr_accessible(*attributes) и attr_protected(*attributes)? Примеры были бы приятными.

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

Ответ 1

attr_accessible (документация) говорит: "Указанные атрибуты доступны, а все остальные защищены" (подумайте об этом как белый список.)

тогда

attr_protected (документация) говорит: "указанные атрибуты защищены и все остальные доступны" (подумайте об этом как черный список.)

Защищенный атрибут - это тот, который может быть явно изменен (например, через атрибут =) и не может быть обновлен посредством массового присвоения (например, с помощью model.update_attributes или путем передачи атрибутов new). Поведение при попытке обновить защищенный атрибут посредством массового назначения зависит от параметра mass_assignment_sanitizer (см. Обновление ниже).

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

Пример:

class User < ActiveRecord::Base
  # explicitly protect is_admin, any new attributes added to the model
  # in future will be unprotected so we need to remember to come back
  # and add any other sensitive attributes here in the future
  attr_protected :is_admin
end

по сравнению с:

class User < ActiveRecord::Base
  # explicitly unprotect name and bio, any new attributes added to the model
  # in the future will need to be listed here if we want them to be accessible
  attr_accessible :name, :bio
end

Теперь, если атрибут is_admin защищен:

> u = User.find_by_name('mikej')
> u.is_admin?
false
> u.update_attributes(:name => 'new name', :is_admin => true)
> u.is_admin?
false
> u.name
"new name" 
> u.is_admin = true # setting it explicitly
> u.save
> u.is_admin?
true

Обновление: более поздние версии Rails представили концепцию дезинфицирующего средства массового назначения для управления поведением при попытках обновить защищенные атрибуты посредством массового присвоения. В Rails 3.2 и позже это можно контролировать, установив mass_assignment_sanitizer в config. По умолчанию необходимо просто зарегистрировать попытки и разрешить выполнение кода, но стандартная конфигурация среды для разработки устанавливает это на :strict, которая возникает как исключение при попытке обновить защищенный атрибут.

Ответ 2

attr_accessible - это белый список для массового присвоения...

class Foo < ActiveRecord::Base #has attributes foo and bar
  attr_accessible :foo
end
f = Foo.new :foo => "test", :bar => "test"
f.foo #=> "test"
f.bar #=> nil

attr_proteceted - черный список для массового присваивания...

class Foo < ActiveRecord::Base #has attributes foo and bar
  attr_protected :bar
end
f = Foo.new :foo => "test", :bar => "test"
f.foo #=> "test"
f.bar #=> nil