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

时间:2012-05-08 19:27:43

标签: ruby-on-rails activerecord ruby-on-rails-3.2

在普通的java中我会使用:

public User(String name, String email) {
  this.name = name;
  this.email = f(email);
  this.admin = false;
}

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

1。覆盖初始化

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

但在创建record from the DB

时可能会错过

2。使用after_initialize回调

通过覆盖它:

def after_initialize(attributes = {}, options = {})
  ...
end

或使用宏:

after_initialize : my_own_little_init
def my_own_little_init(attributes = {}, options = {})
  ...
end

但可能有some deprecation issues

有一些other个链接in SO,但它们可能已过时。


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

5 个答案:

答案 0 :(得分: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

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

User.build_admin(params)

def self.build_admin(params)
  user = User.new(params)
  user.admin = true
  user
end

答案 1 :(得分:15)

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

答案 2 :(得分:5)

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

class User ...
   scope :admins, where(admin: true)

然后您可以同时执行这两项操作:通过admin在管理员状态下创建新用户(即使用true == User.admins.new(...)),并以同样方式获取所有管理员{{ 1}}。

您可以制作一些范围,并使用其中一些范围作为创建/搜索的模板。此外,您可以使用User.admins具有相同含义,但没有默认应用的名称。

答案 3 :(得分:4)

今天早上我正在寻找类似的东西。虽然在数据库中设置默认值显然会起作用,但它似乎打破了Rails关于应用程序处理数据完整性(因此默认值?)的约定。

我偶然发现了post。由于您可能不想立即将记录保存到数据库,我认为最好的方法是通过调用write_attribute()来覆盖initialize方法。

def initialize
  super
  write_attribute(name, "John Doe")
  write_attribute(email,  f(email))
  write_attribute(admin, false)
end

答案 4 :(得分:4)

这适用于rails 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