В Rails, в чем разница между attr_accessor
и attr_accessible
? По моему мнению, использование attr_accessor
используется для создания методов getter и setter для этой переменной, так что мы можем получить доступ к переменной типа Object.variable
или Object.variable = some_value
.
Я читал, что attr_accessible
делает эту переменную доступной для внешнего мира.
Может кто-нибудь, пожалуйста, скажите мне, в чем разница
attr_accessor
- это рубиновый метод, который создает геттер и сеттер. attr_accessible
- это метод Rails, который позволяет передавать значения в массовое присвоение: new(attrs)
или update_attributes(attrs)
.
Здесь массовое назначение:
Order.new({ :type => 'Corn', :quantity => 6 })
Вы можете себе представить, что в заказе также может быть код скидки, скажем: price_off. Если вы не отметили: price_off как attr_accessible, вы перестаете делать вредоносный код так:
Order.new({ :type => 'Corn', :quantity => 6, :price_off => 30 })
Даже если ваша форма не имеет поля для: price_off, если оно в вашей модели доступно по умолчанию. Это означает, что созданный POST все еще может установить его. Использование attr_accessible white перечисляет те вещи, которые могут быть назначены массой.
attr_accessible
? api.rubyonrails.org
Многие люди в этом потоке и в google очень хорошо объясняют, что attr_accessible
указывает белый список атрибутов, которые разрешены для обновления в массе (все атрибуты объектной модели вместе в одно и то же время)
Это главным образом (и только) для защиты вашего приложения от "массового назначения" пиратского эксплойта.
Это объясняется здесь в официальном документе Rails: Массовое присвоение
attr_accessor
- это рубиновый код (быстро), создающий методы setter и getter в классе. Это все.
Теперь то, что отсутствует в качестве объяснения, заключается в том, что когда вы каким-либо образом создаете связь между моделью (Rails) и таблицей базы данных, вы НИКОГДА, НИКОГДА, НИКОГДА не нуждаетесь в attr_accessor
в своей модели для создания сеттеров и геттеров в порядке чтобы иметь возможность изменять записи в таблице.
Это потому, что ваша модель наследует все методы из класса ActiveRecord::Base
, который уже определяет базовые устройства доступа CRUD (Create, Read, Update, Delete) для вас.
Это объясняется в официальном документе здесь Rails Model и здесь Перезаписывание доступа по умолчанию (прокрутите вниз до главы "Перезаписать аксессуар по умолчанию" )
Скажем, например, что у нас есть таблица базы данных, называемая "пользователи", которая содержит три столбца "firstname", "lastname" и "role" :
Инструкции SQL:
CREATE TABLE users (
firstname string,
lastname string
role string
);
Я предположил, что вы установили опцию config.active_record.whitelist_attributes = true
в свой config/environment/production.rb для защиты вашего приложения от эксплойта массового назначения. Это объясняется здесь: Массовое присвоение
Модель Rails отлично работает с моделью ниже:
class User < ActiveRecord::Base
end
Однако вам нужно будет обновлять каждый атрибут пользователя отдельно в вашем контроллере для вашей формы. Вид для работы:
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
Теперь, чтобы облегчить вам жизнь, вы не хотите создавать сложный контроллер для своей модели пользователя.
Таким образом, вы будете использовать специальный метод attr_accessible
в своей модели класса:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
end
Таким образом, вы можете использовать "шоссе" (массовое присвоение) для обновления:
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
Вы не добавили атрибуты "role" в список attr_accessible
, потому что вы не позволяете своим пользователям самостоятельно устанавливать свою роль (например, admin). Вы делаете это самостоятельно на другом специальном представлении администратора.
Хотя в вашем представлении пользователя не отображается поле "роль", пират может легко отправить запрос HTTP POST, который включает "роль" в хеше params. Отсутствующий атрибут "role" на attr_accessible
предназначен для защиты вашего приложения от этого.
Вы все равно можете изменить свой атрибут user.role самостоятельно, как показано ниже, но не со всеми атрибутами.
@user.role = DEFAULT_ROLE
Почему, черт возьми, вы использовали бы attr_accessor
?
Ну, это будет в том случае, если ваша пользовательская форма показывает поле, которое не существует в вашей таблице пользователей в качестве столбца.
Например, скажем, в вашем представлении пользователя отображается поле "please-tell-the-admin-that-I'm-in-here". Вы не хотите хранить эту информацию в своей таблице. Вы просто хотите, чтобы Rails отправил вам электронное письмо, предупреждающее вас о том, что пользователь "сумасшедший";-) подписался.
Чтобы иметь возможность использовать эту информацию, вам нужно временно ее хранить.
Что проще, чем восстановить его в атрибуте user.peekaboo
?
Итак, вы добавляете это поле в свою модель:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
attr_accessor :peekaboo
end
Таким образом, вы сможете сделать образованное использование атрибута user.peekaboo
где-то в вашем контроллере, чтобы отправить электронное письмо или сделать все, что захотите.
ActiveRecord не сохранит атрибут "peekaboo" в вашей таблице, если вы выполните user.save
, потому что она не видит ни одной колонки, соответствующей этому имени в своей модели.
attr_accessor
- это метод Ruby, который предоставляет методы setter и getter для переменной экземпляра с тем же именем. Таким образом, это эквивалентно
class MyModel
def my_variable
@my_variable
end
def my_variable=(value)
@my_variable = value
end
end
attr_accessible
- это метод Rails, который определяет, какие переменные могут быть заданы при массовом присвоении.
Когда вы отправляете форму, и у вас есть что-то вроде MyModel.new params[:my_model]
, тогда вы хотите иметь немного больше контроля, чтобы люди не могли отправлять вещи, которые вы им не хотите.
Вы можете сделать attr_accessible :email
, чтобы, когда кто-то обновляет свою учетную запись, они могут изменить свой адрес электронной почты. Но вы не сделали бы attr_accessible :email, :salary
, потому что тогда человек мог бы установить свою зарплату через подачу формы. Другими словами, они могли взломать свой путь к рейзу.
Такая информация должна быть явно обработана. Просто удалить его из формы недостаточно. Кто-то может пойти с firebug и добавить элемент в форму, чтобы отправить поле зарплаты. Они могли бы использовать встроенный завиток, чтобы представить новую зарплату методу обновления контроллера, они могут создать script, который отправит сообщение с этой информацией.
Итак, attr_accessor
рассказывает о создании методов для хранения переменных, а attr_accessible
- о безопасности массовых присвоений.
attr_accesible
:as
!
attr_accessor
- это код ruby и используется, когда у вас нет столбца в базе данных, но вы хотите показать поле в своих формах. Единственный способ разрешить это - attr_accessor :fieldname
, и вы можете использовать это поле в своем представлении или модели, если хотите, но чаще всего в вашем представлении.
Рассмотрим следующий пример
class Address
attr_reader :street
attr_writer :street
def initialize
@street = ""
end
end
Здесь мы использовали attr_reader
(читаемый атрибут) и attr_writer
(записываемый атрибут) для доступа к цели. Но мы можем достичь той же функциональности, используя attr_accessor
. Короче говоря, attr_accessor обеспечивает доступ как к методам получения, так и к сеттерам.
Модифицированный код ниже
class Address
attr_accessor :street
def initialize
@street = ""
end
end
attr_accessible
позволяет вам перечислять все столбцы, которые вы хотите разрешить массовое присвоение. Противоположностью этому является attr_protected
, что означает это поле. Я НЕ хочу, чтобы кому-то разрешалось назначать массовое присвоение. Скорее всего, это будет поле в вашей базе данных, в котором вы не хотите, чтобы кто-нибудь обезвредил. Как поле статуса или тому подобное.
Быстрый и краткий обзор различий:
attr_accessor
- это простой способ создания аксессуаров чтения и записи в твой класс. Он используется, когда в базе данных нет столбца, но все же хотите показать поле в ваших формах. Это поле является"virtual attribute"
в модели Rails.виртуальный атрибут - атрибут, не соответствующий столбцу в базе данных.
attr_accessible
используется для определения доступных атрибутов по вашим методам контроллера делает доступным свойство для массовое присвоение. Это позволит только доступ к атрибутам, которые вы укажите, отрицая остальное.
attr_accessor
- это метод getter
, setter
.
а attr_accessible
означает, что данный атрибут доступен или нет. это.
Я хочу добавить, что мы должны использовать Сильный параметр вместо attr_accessible
для защиты от массового присвоения.
Ура!
attr_accessor
используется для генерации методов получения и установки. Пожалуйста, смотрите мой ответ на предыдущий вопрос для довольно полного объясненияattr_accessible
: stackoverflow.com/questions/2652907/… затем обновите свой вопрос, если после этого вам понадобятся какие-либо другие конкретные детали.