Использование attr_accessor и attr_accessible в одном и том же поле

Что происходит в фоновом режиме со следующим кодом?

class User < ActiveRecord::Base

 attr_accessor :name
 attr_accessible :name

end

Подсказка: при создании экземпляра класса он будет сохранен в базе данных? Почему или почему нет?


person Magne    schedule 15.01.2011    source источник


Ответы (4)


attr_accessor — это рубиновый код, который используется, когда у вас нет столбца в базе данных, но вы все же хотите отобразить поле в своих формах. Единственный способ разрешить это - attr_accessor :fieldname, и вы можете использовать это поле в своем представлении или модели, если хотите, но в основном в своем представлении.

attr_accessible позволяет вам перечислить все столбцы, для которых вы хотите разрешить массовое назначение, как и ускользнуло выше. Противоположностью этому является attr_protected, что означает, что я НЕ хочу, чтобы кому-либо было разрешено массовое назначение. Более чем вероятно, что это будет поле в вашей базе данных, с которым вы не хотите, чтобы кто-то возился. Например, поле статуса или тому подобное.

person pjammer    schedule 15.01.2011
comment
Единственный лучший ответ, который я видел на этот чрезвычайно важный и основной вопрос. Почему-то это просто обычно не прописано для людей. Спасибо. - person Ethan; 24.02.2011
comment
Это очень хорошее объяснение различий между ними, но это не вопрос: что происходит, когда вы используете их оба в одном и том же поле (или что происходит с настойчивостью). Для этого см. мой краткий ответ ниже. - person Magne; 05.01.2012

В большинстве случаев вам не нужно использовать attr_accessor, если поле является столбцом в таблице users вашей базы данных. ActiveRecord сделает это за вас.

attr_accessible просто позволяет назначать поля через массовое назначение (например, с update_attributes). Это хорошо в целях безопасности. Дополнительные сведения см. в документах по API MassAssignmentSecurity. .

person Andy Lindeman    schedule 15.01.2011

Спасибо всем за быстрые ответы! Я думаю, что ваши ответы в совокупности дали мне кусочки, необходимые для понимания этой головоломки.

(В связанной проблеме я получал много нулевых ошибок, таких как «Объект не поддерживает #inspect» и «ключи неопределенного метода для nil: NilClass». Мне удалось решить это сейчас, удалив поле att_accessor вообще.)

Экспериментируя с этим конкретным случаем, я выяснил следующее:

На самом деле поле :name не будет сохранено в базе данных.

user = User.new(:name=>"somename")

Только установит атрибут для объекта, но не сохранит столбец :name в базе данных. Как показано в следующем выводе консоли rails:

> user
=> <User id: nil, created_at: nil, updated_at: nil>
> user.save
=> true
> user
=> <User id:1, created_at: 2011-01-19 12:37:21, updated_at: 2011-01-19 12:37:21>

Я предполагаю, что это связано с тем, что * установщик, созданный attr_accessor, переопределит установщик ActiveRecord * (который заботится о сохранении базы данных). Однако вы все равно можете получить значение из поля :name из объекта, например:

> user.name
=> "somename"

Итак, в заключение я узнал, что использование атрибута attr_accessor для полей может привести к тому, что они не сохранятся в базе данных. И хотя я думал, что attr_accessible описывает поля в базе данных, которые должны быть доступны извне, в данном случае это не имеет значения.

person Magne    schedule 19.01.2011

Поскольку он наследует ActiveRecord, он будет сохранен при вызове метода save (но не при его создании).

Если у вас нет атрибутов для этой модели, я предполагаю, что ActiveRecord просто сохранит новую строку в базе данных (т. е. ваш объект будет иметь только постоянный id). Это имеет смысл, так как позже вы можете добавить атрибуты в свою модель User, а сохраненные экземпляры по-прежнему должны быть доступны для извлечения.

person David Sulc    schedule 15.01.2011