attr_accessible
(documentation) mówi "określone atrybuty są dostępne, a wszyscy inni są chronione" (myślę o nim jako whitelisting.)
natomiast
attr_protected
(documentation) mówi „określone atrybuty są chronione i wszystkie inne są dostępne "(pomyśl o tym jako blacklisting.)
Atrybut chroniony można zmodyfikować tylko jawnie (np. atrybut =) i nie można go zaktualizować poprzez przypisanie masy (np. używając model.update_attributes
lub przekazując atrybuty do new
). Zachowanie po próbie zaktualizowania chronionego atrybutu poprzez przypisanie masy zależy od ustawienia mass_assignment_sanitizer
(zobacz poniższą aktualizację).
Klasycznym przykładem może być model User
z atrybutem is_admin
, który można zabezpieczyć, aby zapobiec wysyłaniu formularzy, co pozwoliłoby ustawić dowolnego użytkownika jako administratora.
przykład:
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
porównaniu z:
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
Teraz, zakładając atrybut is_admin
jest chroniony:
> 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
Aktualizacja: nowszych wersjach Rails wprowadził pojęcie z środek dezynfekcji masy do kontrolowania zachowania po próbach aktualizacji chronionych atrybutów poprzez przypisanie masy. W Railsach 3.2 i nowszych można to kontrolować, ustawiając mass_assignment_sanitizer
w config. Wartością domyślną jest po prostu zarejestrowanie prób i zezwolenie na kontynuowanie kodu, ale standardowa konfiguracja środowiska dla zestawów ustawia ją na :strict
, co podnosi jako wyjątek przy próbie aktualizacji chronionego atrybutu.
możemy ich używać razem? – Salil
tak, ale atrybuty mogą być różne – fl00r
Nie, możesz użyć tylko jednego lub drugiego. Jeśli uwzględnisz obie klasy, nie zobaczysz błędu, gdy klasa zostanie załadowana po raz pierwszy, ale prawdopodobnie pojawi się jako 'NoMethodError: Masz obiekt zerowy, gdy się tego nie spodziewałeś!' Przy próbie użycia klasa. – mikej