alias_attribute vs read_attribute和write_attribute

时间:2014-06-07 02:40:36

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

我在没有rails的情况下使用ActiveRecord。一切都很好,除了一些奇怪的怪癖与一些帮助方法,我写的,我希望有人可以解释。我有一个遗留数据库的模型。有些列名称中包含“#”,因此我使用read_attribute和write_attribute在模型中定义它们。例如(准确的例子,但简化):

class Product < ActiveRecord::Base
  alias_attribute :name, :pname

  def sale_number
    read_attribute 'sale#'
  end

  def sale_number=(value)
    write_attribute 'sale#', value
  end

  def self.helper_with_alias
    where(name: 'My Product Name')
  end

  def self.helper_with_attribute
    where(sale_number: 5)
  end
end

如果我致电Product.helper_with_alias,一切都按预期进行。但是,当我致电Product.helper_with_attribute时,我收到ActiveRecord::StatementInvalid错误,指出无法找到sale_number列。另外,如果我将helper_with_attribute中的代码替换为where('sale#' => 5),一切正常。

为什么ActiveRecord正确地将pname别名变为name但未将sale#正确别名变为sale_number

1 个答案:

答案 0 :(得分:1)

错误是因为您在where子句中使用了一个不存在的列。您还需要将sale#的alias_attribute定义为sale_number

在你的模型中,你可以这样做:

class Product < ActiveRecord::Base
  alias_attribute :sale_number, :"sale#"

  def self.helper_with_attribute
    where(sale_number: 5)
  end
end

使用此功能,您无需为分配和检索目的定义setter和getter,因此您可以删除sale_numbersale_number=(value)方法。使用alias_attributegetters, setters and query methods已经是别名!

  

为什么ActiveRecord正确地将pname别名为name但不正确   别名销售#到sale_number?

这是因为您定义了alias_attribute :name, :pname,它将setter,getters和query方法作为现有pname属性的别名提供。但是,对于sale_number,您只定义了一个getter和setter,而不是查询方法。