Использование attr_accessor и attr_accessible в одном поле - PullRequest
21 голосов
/ 15 января 2011

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

class User < ActiveRecord::Base

 attr_accessor :name
 attr_accessible :name

end

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

Ответы [ 4 ]

70 голосов
/ 15 января 2011

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

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

5 голосов
/ 15 января 2011

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

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

4 голосов
/ 19 января 2011

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

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

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

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

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

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

> 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 описывает поля в базе данных, которые должны быть доступны извне, в этом случае, похоже, это не имеет значения.

1 голос
/ 15 января 2011

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

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

...