Ruby-on-rails 如何使用 Rails 中的值初始化 ActiveRecord?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10505166/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to initialize an ActiveRecord with values in Rails?
提问by Asaf
In plain java I'd use:
在普通的 Java 中,我会使用:
public User(String name, String email) {
this.name = name;
this.email = f(email);
this.admin = false;
}
However, I couldn't find a simple standard way to do in rails (3.2.3), with ActiveRecords.
但是,我无法在 Rails (3.2.3) 中使用 ActiveRecords 找到一种简单的标准方法。
1. override initialize
1.覆盖初始化
def initialize(attributes = {}, options = {})
@name = attributes[:name]
@email = f(attributes[:email])
@admin = false
end
but it might be missed when creating a record from the DB
2. using the after_initializecallback
2.使用after_initialize回调
by overriding it:
通过覆盖它:
def after_initialize(attributes = {}, options = {})
...
end
or with the macro:
或使用宏:
after_initialize : my_own_little_init
def my_own_little_init(attributes = {}, options = {})
...
end
but there may be some deprecation issues.
但可能存在一些弃用问题。
There are some otherlinks in SO, but they may be out-of-date.
So, what's the correct/standard method to use?
那么,正确/标准的使用方法是什么?
采纳答案by Jesse Wolgamott
Your default values should be defined in your Schema when they will apply to ALL records. So
当您的默认值应用于所有记录时,应在您的架构中定义它们。所以
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
Here, every new Post will have false for published. If you want default values at the object level, it's best to use Factory style implementations:
在这里,每一个新的 Post 都会有 false 来发布。如果您想要对象级别的默认值,最好使用工厂样式实现:
User.build_admin(params)
def self.build_admin(params)
user = User.new(params)
user.admin = true
user
end
回答by Mauro George
According to Rails Guides the best way to do this is with the after_initialize. Because with the initialize we have to declare the super, so it is best to use the callback.
根据 Rails 指南,最好的方法是使用after_initialize。因为在初始化时我们必须声明超级,所以最好使用回调。
回答by jdoe
One solution that I like is via scopes:
我喜欢的一种解决方案是通过范围:
class User ...
scope :admins, where(admin: true)
Then you can do both: create new User in the admin status(i.e. with admin==true) via User.admins.new(...)and also fetch all your admins in the same way User.admins.
然后,您可以同时执行以下操作:通过在管理员状态(即使用admin== true)创建新用户User.admins.new(...)并以相同方式获取所有管理员User.admins。
You can make few scopes and use few of them as templates for creating/searching. Also you can use default_scopewith the same meaning, but without a name as it is applied by default.
您可以创建很少的范围并使用其中的一些作为创建/搜索的模板。您也可以使用default_scope相同的含义,但没有名称,因为它是默认应用的。
回答by clekstro
I was searching for something similar this morning. While setting a default value in the database will obviously work, it seems to break with Rails' convention of having data integrity (and therefore default values?) handled by the application.
今天早上我正在寻找类似的东西。虽然在数据库中设置默认值显然会起作用,但它似乎违反了 Rails 的约定,即由应用程序处理数据完整性(以及默认值?)。
I stumbled across this post. As you might not want to save the record to the database immediately, I think the best way is to overwrite the initialize method with a call to write_attribute().
我偶然发现了这篇文章。由于您可能不想立即将记录保存到数据库中,我认为最好的方法是通过调用write_attribute().
def initialize
super
write_attribute(name, "John Doe")
write_attribute(email, f(email))
write_attribute(admin, false)
end
回答by Harry Fairbanks
This will work in rails 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

