Sql 在Rails ActiveRecord模型中,使用after_初始化回调是一个非常糟糕的主意吗?

Sql 在Rails ActiveRecord模型中,使用after_初始化回调是一个非常糟糕的主意吗?,sql,ruby-on-rails,ruby-on-rails-3,activerecord,callback,Sql,Ruby On Rails,Ruby On Rails 3,Activerecord,Callback,假设我们有这个模型 class Account < ActiveRecord::Base after_initialize :set_name def set_name self.name = ‘My Account’ end end 然后此执行会引发以下错误,因为set_name回调使用的属性尚未“加载”或选择到查询返回的记录中 ActiveModel::MissingAttributeError: missing attribute: name 幸运的是,在某

假设我们有这个模型

class Account < ActiveRecord::Base
  after_initialize :set_name

  def set_name
    self.name = ‘My Account’
  end
end
然后此执行会引发以下错误,因为set_name回调使用的属性尚未“加载”或选择到查询返回的记录中

ActiveModel::MissingAttributeError: missing attribute: name
幸运的是,在某些特定情况下,我可以执行相同的sql查询,而无需使用帐户模型来获得所需的结果

sql = Account.group(:name).select("count(*), id").to_sql
ActiveRecord::Base.connection.execute(sql).first
=> #<Mysql2::Result:0x00000106eddbc0>
sql=Account.group(:name)。选择(“count(*),id”)。以使用sql
ActiveRecord::Base.connection.execute(sql).first
=> #

但问题是,如果我想获取Account对象而不是Mysql2::Result one,该怎么办?
.select
方法是否应返回“complete”对象及其所有属性(例如,用Nil填充缺少的列)?或者在初始化ActiveRecord模型的回调后使用是一个非常糟糕的主意?当然,我们也可以在回调中添加一些代码来检查属性是否存在,但在我看来,这在OO语言中是不自然的,或者听起来很奇怪。

初始化后的
的大多数用法可以(并且应该)在相应的数据库列上用默认值替换。如果要将属性设置为常量值,则可能需要将其作为备选方案


编辑:如果该值不是常量,则调用
的has_attribute?(:name)
将防止此错误-

不,这不是一个坏主意,事实上我在工作中经常使用它。这方面的有效用例是,在尝试对对象执行任何操作之前,希望代码运行。下面是提供的一些过滤器的分类

# Before you intend to do anything with the object
after_initialize

# Before you intend to save the object
before_save

# After you've saved the object
after_save

# Before you save a new record
before_create

# After you create a new object
after_create

假设回调方法基于name字段检查条件,而不是放置默认名称。如果self.name==,我们仍然会遇到同样的问题
将引发异常。因为“在您打算对对象执行任何操作之前”,如果您运行如示例所示的查询,它将引发错误。请仔细阅读问题,因为问题不是那么简单,我相信答案也不是那么简单。让我知道你的想法。
# Before you intend to do anything with the object
after_initialize

# Before you intend to save the object
before_save

# After you've saved the object
after_save

# Before you save a new record
before_create

# After you create a new object
after_create