Подтвердить что ты не робот

Как инициализировать 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, но они могут быть устаревшими.


Итак, какой правильный/стандартный метод использовать?

4b9b3361

Ответ 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