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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 03:22:09  来源:igfitidea点击:

How to initialize an ActiveRecord with values in Rails?

ruby-on-railsactiverecordruby-on-rails-3.2

提问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 中还有一些其他链接,但它们可能已过时。



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