Многие пользователи в этой теме и в Google очень хорошо объясняют, что attr_accessible
указывает белый список атрибутов, которые разрешено обновлять массово ( все атрибуты объектной модели одновременно ). Это главным образом (и только) для защиты вашего приложения. из "Массового задания" пиратский подвиг.
Это объясняется здесь на официальном Rails doc: Mass Assignment
attr_accessor
код ruby для быстрого создания методов установки и получения в классе. Вот и все.
Теперь в качестве объяснения не хватает того, что когда вы каким-либо образом создаете связь между моделью (Rails) с таблицей базы данных, вам НИКОГДА, НИКОГДА, НИКОГДА не нужно attr_accessor
в вашей модели создавать сеттеры и геттеры, чтобы иметь возможность изменять ваши записи таблицы.
Это связано с тем, что ваша модель наследует все методы ActiveRecord::Base
класса, который уже определяет для вас основные средства доступа CRUD (Create, Read, Update, Delete). Это объясняется в официальном документе здесь Rails Model и здесь Overwriting accessor по умолчанию (прокрутите вниз до главы «Перезаписать accessor по умолчанию»)
Скажем, например, что: у нас есть таблица базы данных с именем «users», которая содержит три столбца «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
Теперь, чтобы облегчить вашу жизнь, вы не хотите делать сложный контроллер для вашей модели 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). Вы делаете это самостоятельно на другом специальном админском View.
Хотя ваше представление пользователя не отображает поле «роль», пират может легко отправить HTTP-запрос POST, включающий «роль» в хэш params. Отсутствующий атрибут "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
Таким образом, вы сможете грамотно использовать user.peekaboo
атрибут где-то на вашем контроллере, чтобы отправлять электронную почту или делать все, что захотите.
ActiveRecord не сохранит атрибут «peekaboo» в вашей таблице, когда вы это сделаете, user.save
потому что она не видит ни одного столбца, соответствующего этому имени, в ее модели.
attr_accessor
используется для генерации методов получения и установки. Пожалуйста, смотрите мой ответ на предыдущий вопрос для довольно подробного объясненияattr_accessible
: stackoverflow.com/questions/2652907/… затем обновите свой вопрос, если вам понадобятся какие-либо другие конкретные детали после этого.