Wiele osób w tym wątku i w Google bardzo dobrze wyjaśnia, które attr_accessibleokreś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_accessorto 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_accessorw 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::Baseklasy, 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 = truew 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_accessiblespecjalną 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_accessiblelisty, 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_accessiblesł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.peekabooatrybucie?
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.peekabooatrybut 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.saveponieważ nie widzi żadnej kolumny pasującej do tej nazwy w swoim modelu.
attr_accessorjest 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.