Как инициализировать ActiveRecord со значениями в Rails?
В простой java я бы использовал:
public User(String name, String email) {
this.name = name;
this.email = f(email);
this.admin = false;
}
Однако я не смог найти простой стандартный способ сделать в рельсах (3.2.3) с помощью ActiveRecords.
1. переопределить инициализацию
def initialize(attributes = {}, options = {})
@name = attributes[:name]
@email = f(attributes[:email])
@admin = false
end
но он может быть пропущен при создании записи из базы данных
2. используя обратный вызов after_initialize
переопределив его:
def after_initialize(attributes = {}, options = {})
...
end
или с макросом:
after_initialize : my_own_little_init
def my_own_little_init(attributes = {}, options = {})
...
end
но могут быть некоторые проблемы с устаревшими версиями.
Есть несколько других ссылок в формате SO, но они могут быть устаревшими.
Итак, какой правильный/стандартный метод использовать?
Ответы
Ответ 1
Значения по умолчанию должны быть определены в вашей схеме, когда они будут применяться ко всем записям. Так
def change
creates_table :posts do |t|
t.boolean :published, default: false
t.string :title
t.text :content
t.references :author
t.timestamps
end
end
Здесь каждое новое сообщение будет иметь false для публикации. Если вам нужны значения по умолчанию на уровне объекта, лучше всего использовать реализации стиля Factory:
User.build_admin(params)
def self.build_admin(params)
user = User.new(params)
user.admin = true
user
end
Ответ 2
В соответствии с Rails Guides лучший способ сделать это - after_initialize. Поскольку при инициализации мы должны объявить супер, поэтому лучше использовать обратный вызов.
Ответ 3
Единственное решение, которое мне нравится, - через области:
class User ...
scope :admins, where(admin: true)
Затем вы можете сделать оба: создать нового пользователя в статусе администратора (т.е. с помощью admin
== true
) через User.admins.new(...)
, а также получить все ваши администраторы таким же образом User.admins
.
Вы можете сделать несколько областей и использовать несколько из них в качестве шаблонов для создания/поиска. Также вы можете использовать default_scope
с тем же значением, но без имени, поскольку оно применяется по умолчанию.
Ответ 4
Я искал что-то подобное этим утром. Хотя установка значения по умолчанию в базе данных, очевидно, будет работать, кажется, что разрыв с соглашением Rails о целостности данных (и, следовательно, значения по умолчанию?), Обрабатываемых приложением.
Я наткнулся на это сообщение . Поскольку вы можете не захотеть немедленно сохранить запись в базе данных, я думаю, что лучший способ - перезаписать метод initialize вызовом write_attribute()
.
def initialize
super
write_attribute(name, "John Doe")
write_attribute(email, f(email))
write_attribute(admin, false)
end
Ответ 5
Это будет работать в рельсах 4.
def initialize(params)
super
params[:name] = params[:name] + "xyz"
write_attribute(:name, params[:name])
write_attribute(:some_other_field, "stuff")
write_attribute(:email, params[:email])
write_attribute(:admin, false)
end