Многие в этой теме и в Google очень хорошо объясняют, что attr_accessible
задает белый список атрибутов, которые разрешено обновлять массово ( все атрибуты объектной модели одновременно) ) Это главным образом (и только) для защиты вашего приложения от пиратского эксплойта «Массовое назначение».
Это объясняется здесь на официальном документе Rails: Массовое назначение
attr_accessor
- это код ruby для (быстрого) создания методов установки и получения в классе.Вот и все.
Теперь в качестве объяснения не хватает того, что когда вы каким-либо образом создаете связь между моделью (Rails) и таблицей базы данных, вам НИКОГДА, НИКОГДА, НИКОГДА не потребуется attr_accessor
в вашей модели, чтобысоздавать сеттеры и геттеры, чтобы иметь возможность изменять записи вашей таблицы.
Это потому, что ваша модель наследует все методы из класса ActiveRecord::Base
, который уже определяет основные средства доступа CRUD (Create, Read, Update, Delete) для тебя.Это объясняется в официальном документе здесь Модель Rails и здесь Перезапись доступа по умолчанию (прокрутите вниз до главы «Перезапись доступа по умолчанию»)
Скажите, например, что:у нас есть таблица базы данных с именем «users», которая содержит три столбца «firstname», «lastname» и «role»:
инструкции SQL:
CREATE TABLE users (
firstname string,
lastname string
role string
);
Я предположил, что вы установили опциюconfig.active_record.whitelist_attributes = true
в вашем config / environment / production.rb для защиты вашего приложения от эксплойта Mass назначений.Это объясняется здесь: Mass Assignment
Ваша модель 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
Теперь, чтобы упростить вашу жизнь, вы не хотите создавать сложный контроллер для вашей модели User.Таким образом, вы будете использовать специальный метод 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, включающий «роль» в хэш параметров.Отсутствующий атрибут "role" в attr_accessible
предназначен для защиты вашего приложения от этого.
Вы по-прежнему можете изменять свой атрибут user.role, как показано ниже, но не со всеми атрибутами вместе.
@user.role = DEFAULT_ROLE
Какого черта вы используете attr_accessor
?
Ну, это будет в том случае, если ваша пользовательская форма показывает поле, которое не существуетв вашей таблице пользователей в виде столбца.
Например, скажем, в вашем пользовательском представлении отображается поле «Пожалуйста, скажите администратору, что я здесь».Вы не хотите хранить эту информацию в вашей таблице.Вы просто хотите, чтобы Rails отправил вам электронное письмо с предупреждением о том, что один «сумасшедший» ;-) пользователь подписался.
Чтобы использовать эту информацию, вам нужно временно где-то ее хранить.Что может быть проще, чем восстановить его в атрибуте user.peekaboo
?
Итак, вы добавите это поле в свою модель:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
attr_accessor :peekaboo
end
Таким образом, вы сможете грамотно использовать *Атрибут 1070 * где-нибудь в вашем контроллере для отправки электронной почты или выполнения любых действий.
ActiveRecord не сохранит атрибут "peekaboo" в вашей таблице, когда вы выполните user.save
, потому что она не видитлюбой столбец, соответствующий этому имени в ее модели.