Wiele osób w tym wątku i w Google bardzo dobrze wyjaśnia, które attr_accessible
określa białą listę atrybutów, które mogą być aktualizowane zbiorczo ( wszystkie atrybuty modelu obiektowego jednocześnie ). Ma to głównie (i tylko) na celu ochronę twojej aplikacji z exploitu pirackiego „Mass Assignment”.
Jest to wyjaśnione tutaj w oficjalnym dokumencie Rails: Mass Assignment
attr_accessor
to ruby kod do (szybkiego) tworzenia metod ustawiających i pobierających w klasie. To wszystko.
Wyjaśnieniem jest to, że kiedy w jakiś sposób tworzysz połączenie między modelem (Rails) z tabelą bazy danych, NIGDY, NIGDY, NIGDY nie potrzebujesz attr_accessor
w swoim modelu, aby tworzyć setery i gettery, aby móc modyfikować swój rekordy tabeli.
Wynika to z faktu, że Twój model dziedziczy wszystkie metody z ActiveRecord::Base
klasy, która już definiuje podstawowe akcesoria CRUD (tworzenie, czytanie, aktualizacja, usuwanie). Jest to wyjaśnione w oficjalnym dokumencie tutaj Rails Model i tutaj Nadpisywanie domyślnego akcesorium (przewiń w dół do rozdziału „Nadpisz domyślnego akcesorium”)
Powiedz na przykład, że: mamy tabelę bazy danych o nazwie „użytkownicy”, która zawiera trzy kolumny „imię”, „nazwisko” i „rola”:
Instrukcje SQL:
CREATE TABLE users (
firstname string,
lastname string
role string
);
Zakładałem, że ustawiłeś opcję config.active_record.whitelist_attributes = true
w config / environment / production.rb, aby chronić swoją aplikację przed exploitem Mass Assignment. Wyjaśniono to tutaj: Przydział masowy
Twój model Rails będzie idealnie współpracował z poniższym modelem:
class User < ActiveRecord::Base
end
Musisz jednak zaktualizować każdy atrybut użytkownika osobno w kontrolerze, aby widok formularza działał:
def update
@user = User.find_by_id(params[:id])
@user.firstname = params[:user][:firstname]
@user.lastname = params[:user][:lastname]
if @user.save
# Use of I18 internationalization t method for the flash message
flash[:success] = t('activerecord.successful.messages.updated', :model => User.model_name.human)
end
respond_with(@user)
end
Teraz, aby ułatwić ci życie, nie chcesz tworzyć skomplikowanego kontrolera dla swojego modelu użytkownika. Więc zastosujesz attr_accessible
specjalną metodę w swoim modelu klasy:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
end
Możesz więc użyć „autostrady” (przypisanie masowe) do aktualizacji:
def update
@user = User.find_by_id(params[:id])
if @user.update_attributes(params[:user])
# Use of I18 internationlization t method for the flash message
flash[:success] = t('activerecord.successful.messages.updated', :model => User.model_name.human)
end
respond_with(@user)
end
Nie dodałeś atrybutów „rola” do attr_accessible
listy, ponieważ nie pozwalasz użytkownikom na samodzielne ustawianie swojej roli (np. Admin). Robisz to sam na innym specjalnym widoku administratora.
Chociaż twój widok użytkownika nie pokazuje pola „rola”, pirat może z łatwością wysłać żądanie HTTP POST zawierające „rolę” w haszowaniu parametrów. Brak atrybutu „rola” attr_accessible
służy do ochrony aplikacji przed tym.
Nadal możesz samodzielnie modyfikować atrybut user.role, jak poniżej, ale nie wszystkie atrybuty razem.
@user.role = DEFAULT_ROLE
Dlaczego, do diabła, miałbyś skorzystać attr_accessor
?
Tak byłoby w przypadku, gdy formularz użytkownika pokazuje pole, które nie istnieje w tabeli użytkowników jako kolumna.
Załóżmy na przykład, że Twój widok użytkownika pokazuje pole „proszę powiedzieć administratorowi, że jestem tutaj”. Nie chcesz przechowywać tych informacji w swoim stole. Chcesz, aby Railsy wysłały Ci wiadomość e-mail z ostrzeżeniem, że jeden „szalony” ;-) użytkownik zasubskrybował.
Aby móc skorzystać z tych informacji, musisz je gdzieś tymczasowo przechowywać. Czy jest coś łatwiejszego niż odzyskanie go w user.peekaboo
atrybucie?
Więc dodajesz to pole do swojego modelu:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
attr_accessor :peekaboo
end
Dzięki temu będziesz mógł w przemyślany sposób wykorzystać ten user.peekaboo
atrybut gdzieś w kontrolerze, aby wysłać wiadomość e-mail lub zrobić co chcesz.
ActiveRecord nie zapisze atrybutu „peekaboo” w twojej tabeli, kiedy to zrobisz, user.save
ponieważ nie widzi żadnej kolumny pasującej do tej nazwy w swoim modelu.
attr_accessor
jest używany do generowania metod pobierających i ustawiających. Zapoznaj się z moją odpowiedzią na poprzednie pytanie, aby uzyskać dość wyczerpujące wyjaśnienieattr_accessible
: stackoverflow.com/questions/2652907/…, a następnie zaktualizuj swoje pytanie, jeśli potrzebujesz później innych szczegółowych informacji.