如何使用Rails中的值初始化ActiveRecord?

Asa*_*saf 25 activerecord ruby-on-rails ruby-on-rails-3.2

在普通的java中我会使用:

public User(String name, String email) {
  this.name = name;
  this.email = f(email);
  this.admin = false;
}
Run Code Online (Sandbox Code Playgroud)

但是,我在使用ActiveRecords的rails(3.2.3)中找不到简单的标准方法.

1.覆盖初始化

def initialize(attributes = {}, options = {})
  @name  = attributes[:name]
  @email = f(attributes[:email])
  @admin = false
end
Run Code Online (Sandbox Code Playgroud)

但是从DB创建记录时可能会错过

2.使用after_initialize回调

通过覆盖它:

def after_initialize(attributes = {}, options = {})
  ...
end
Run Code Online (Sandbox Code Playgroud)

或者用宏:

after_initialize : my_own_little_init
def my_own_little_init(attributes = {}, options = {})
  ...
end
Run Code Online (Sandbox Code Playgroud)

但可能存在一些弃用问题.

SO中还有其他一些链接,但它们可能已过时.


那么,使用什么是正确/标准的方法?

Jes*_*ott 17

当应用于所有记录时,应在架构中定义默认值.所以

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
Run Code Online (Sandbox Code Playgroud)

在这里,每个新帖子都会有错误发布.如果要在对象级别使用默认值,最好使用Factory样式实现:

User.build_admin(params)

def self.build_admin(params)
  user = User.new(params)
  user.admin = true
  user
end
Run Code Online (Sandbox Code Playgroud)


Mau*_*rge 15

根据Rails指南,最好的方法是使用after_initialize.因为初始化我们必须声明超级,所以最好使用回调.

  • 链接已断开,“ after_create”是否是新的“ after_intitialize”? (2认同)

jdo*_*doe 5

我喜欢的一个解决方案是通过范围:

class User ...
   scope :admins, where(admin: true)
Run Code Online (Sandbox Code Playgroud)

然后你可以做到这两点:在管理状态下创建新用户(即使用admin== true),User.admins.new(...)并以同样的方式获取所有管理员User.admins.

您可以制作一些范围,并使用其中的少数范围作为创建/搜索的模板.您也可以使用default_scope相同的含义,但没有默认应用的名称.