Różnica między attr accessor a attr accessor
W Rails, jaka jest różnica między attr_accessor
a attr_accessible
? Z mojego zrozumienia, użycie attr_accessor
jest używane do tworzenia metod getter i setter dla tej zmiennej, tak że możemy uzyskać dostęp do zmiennej jak Object.variable
lub Object.variable = some_value
.
Czytałem, że attr_accessible
czyni tę specyficzną zmienną dostępną dla świata zewnętrznego.
Czy ktoś może mi powiedzieć jaka jest różnica
6 answers
attr_accessor
jest metodą Ruby, która tworzy getter i setter. {[3] } jest metodą Rails, która pozwala przekazać wartości do przypisania masy: new(attrs)
lub update_attributes(attrs)
.
Oto zadanie masowe:
Order.new({ :type => 'Corn', :quantity => 6 })
Możesz sobie wyobrazić, że zamówienie może mieć również kod rabatowy, powiedzmy :price_off
. Jeśli nie oznaczysz :price_off
jako attr_accessible
, powstrzymasz złośliwy kod przed wykonywaniem takich czynności:
Order.new({ :type => 'Corn', :quantity => 6, :price_off => 30 })
Nawet jeśli twój formularz nie ma pola dla :price_off
, jeśli jest w twoim modelu jest dostępny przez default. Oznacza to, że spreparowany POST nadal może go ustawić. Używając białej listy attr_accessible
te rzeczy, które można przypisać masowo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-15 23:24:04
Wiele osób w tym wątku i w google wyjaśnia bardzo dobrze, że attr_accessible
określa białą listę atrybutów, które mogą być aktualizowane zbiorczo ( wszystkie atrybuty modelu obiektowego razem w tym samym czasie )
Służy to głównie (i tylko) ochronie aplikacji przed" masowym przypisaniem " pirackiego exploita.
To jest wyjaśnione tutaj na oficjalnym Rails doc : Mass assign
attr_accessor
jest kodem ruby do (szybkiego) tworzenia metod setter i getter w klasy. To wszystko.
Teraz brakuje wyjaśnienia, że kiedy tworzysz w jakiś sposób połączenie pomiędzy modelem (Rails) z tabelą bazy danych, nigdy, nigdy, nigdy nie potrzebujesz attr_accessor
w swoim modelu, aby tworzyć settery i gettery, aby móc modyfikować rekordy tabeli.
Dzieje się tak dlatego, że twój model dziedziczy wszystkie metody z klasy ActiveRecord::Base
, która już definiuje podstawowe Accesory CRUD (Create, Read, Update, Delete).
Wyjaśniono to w oficjalnym dokumencie tutaj Rails Model i tutaj nadpisywanie domyślnego accesora (przewiń w dół do rozdziału "nadpisywanie domyślnego accesora")
Powiedzmy na przykład, że: mamy tabelę bazy danych o nazwie "users", która zawiera trzy kolumny "firstname", "lastname" i "role":
Instrukcje SQL:
CREATE TABLE users (
firstname string,
lastname string
role string
);
Założyłem, że ustawiłeś opcję config.active_record.whitelist_attributes = true
w swoim config / environment / production.rb w celu ochrony Twojej aplikacji przed masowym przypisaniem exploita. Jest to wyjaśnione tutaj : Przypisanie Masy
Twój model Rails będzie doskonale współpracować z Modelem tutaj poniżej:
class User < ActiveRecord::Base
end
Jednak będziesz musiał 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ć sobie życie, nie chcesz robić skomplikowanego kontrolera dla swojego modelu użytkownika.
Więc użyjesz attr_accessible
specjalnej metody w swoim modelu klasowym:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
end
Więc możesz użyć "highway" (Mass assignment), aby zaktualizować :
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 listy attr_accessible
, ponieważ nie pozwalasz użytkownikom samodzielnie ustawiać swojej roli (np. admin). Robisz to sam na innym specjalnym widoku administratora.
Chociaż widok użytkownika nie pokazuje pola "rola", pirat może łatwo wysłać żądanie HTTP POST, które zawiera "rolę" w hash params. Brakujący atrybut "rola" na attr_accessible
ma chronić Twoją aplikację przed tym.
Nadal możesz modyfikować swojego użytkownika.atrybut roli samodzielnie jak poniżej, ale nie ze wszystkimi atrybutami razem.
@user.role = DEFAULT_ROLE
Po jaką cholerę miałbyś używać attr_accessor
?
Cóż, byłoby tak w przypadku, gdy formularz użytkownika pokazuje pole, które nie istnieje w tabeli użytkowników jako kolumna.
Na przykład, powiedzmy, że twój widok użytkownika pokazuje pole" please-tell-the-admin-that-I 'm-in-here". Nie chcesz przechowywać tych informacji w tabeli. Po prostu chcesz, żeby Rails wysłał Ci e-mail z ostrzeżeniem, że jeden "szalony"; -) użytkownik ma subscribed.
Aby móc skorzystać z tych informacji, musisz je tymczasowo gdzieś przechowywać.
Co jest łatwiejsze niż odzyskanie go w atrybucie user.peekaboo
?
Więc dodajesz to pole do swojego modelu:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
attr_accessor :peekaboo
end
Więc będziesz mógł wykorzystać atrybut user.peekaboo
gdzieś w kontrolerze, aby wysłać e-mail lub zrobić, co chcesz.
ActiveRecord nie zapisze atrybutu "peekaboo" w tabeli po wykonaniu user.save
, ponieważ nie widzi żadnego kolumna pasująca do tej nazwy w jej modelu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-02 12:56:58
attr_accessor
jest metodą Ruby, która daje metody setter i getter do zmiennej instancji o tej samej nazwie. Jest więc odpowiednikiem
class MyModel
def my_variable
@my_variable
end
def my_variable=(value)
@my_variable = value
end
end
attr_accessible
jest metodą Rails, która określa, jakie zmienne można ustawić w przypisaniu masowym.
Kiedy przesyłasz formularz i masz coś w rodzaju MyModel.new params[:my_model]
, chcesz mieć trochę większą kontrolę, aby ludzie nie mogli przesyłać rzeczy, których nie chcesz.
Można zrobić attr_accessible :email
tak, że gdy ktoś aktualizuje swoje konto, mogą zmienić swój adres e-mail. Ale nie zrobiłbyś tego, bo wtedy ktoś mógłby ustawić swoją pensję poprzez złożenie formularza. Innymi słowy, mogą zhakować drogę do podwyżki.
Tego rodzaju informacje muszą być wyraźnie obsługiwane. Samo usunięcie go z formularza nie wystarczy. Ktoś mógłby wejść z firebug i dodać element do formularza, aby przesłać pole wynagrodzenia. Mogą wykorzystać wbudowany curl do przesłania nowej pensji do metody aktualizacji kontrolera, oni może utworzyć skrypt, który przesyła post z tymi informacjami.
Więc {[1] } chodzi o tworzenie metod do przechowywania zmiennych, a {[2] } o bezpieczeństwo przypisań masowych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-12 14:48:48
attr_accessor
jest kodem ruby i jest używany, gdy nie masz kolumny w bazie danych, ale nadal chcesz pokazać pole w formularzach. Jedynym sposobem na to jest attr_accessor :fieldname
i możesz użyć tego pola w widoku, lub modelu, jeśli chcesz, ale głównie w widoku.
Rozważmy następujący przykład
class Address
attr_reader :street
attr_writer :street
def initialize
@street = ""
end
end
Tutaj użyliśmy attr_reader
(atrybut readable ) oraz attr_writer
(atrybut zapisywalny ) dla dostępu do celu. Ale możemy osiągnąć tę samą funkcjonalność za pomocą attr_accessor
. W skrócie, attr_accessor zapewnia dostęp zarówno do metod getter, jak i setter.
Tak zmodyfikowany kod jest jak poniżej
class Address
attr_accessor :street
def initialize
@street = ""
end
end
attr_accessible
pozwala na wyświetlenie wszystkich kolumn, które chcesz zezwolić na przypisanie masy. Przeciwieństwem tego jest attr_protected
, co oznacza, że nie chcę, aby ktokolwiek miał możliwość przypisania masy do tego pola. Bardziej niż prawdopodobne, że będzie to pole w Twojej bazie danych, z którym nie chcesz, aby ktoś się kręcił. Jak Pole statusu, lub tym podobne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-10 12:09:23
W dwóch słowach:
attr_accessor
Na getter
, setter
metoda.
a także mając na uwadze attr_accessible
oznacza to, że dany atrybut jest dostępny lub nie. to wszystko.
Chciałbym dodać, że powinniśmy używać silnego parametru zamiast attr_accessible
do ochrony przed przesunięciem masy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-18 11:12:57
Szybki i zwięzły przegląd różnic:
attr_accessor
jest łatwym sposobem tworzenia accesorów do odczytu i zapisu w twoja klasa. Jest używany, gdy nie masz kolumny w bazie danych, ale nadal chcesz pokazać pole w formularzach. To pole jest“virtual attribute”
w modelu Rails.Atrybut wirtualny - atrybut nie odpowiadający kolumnie w bazie danych.
attr_accessible
służy do identyfikacji atrybutów, które są dostępne przez kontrolera metody udostępnia właściwość dla przydział masowy.. Pozwoli tylko na dostęp do atrybutów, które określ, zaprzeczając reszcie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-31 06:30:45