将primary_key别名为" id"时,Active Record返回null。

时间:2016-11-03 14:12:36

标签: ruby-on-rails activerecord

我希望别名数据库字段,但将primary_key别名为" id"将空白其值:

class XXX < ActiveRecord::Base
  self.table_name = 'XXX'
  self.primary_key = 'xxx_id'

  def self.get()
    self.select(
        primary_key + ' AS id',
        'xxx_itmno AS product_number',
        'xxx_qty AS qty'
    )
  end

输出:

[{
  id: null,
  product_number: 123,
  qty: 2
}]

问题1.解决此问题的最简单方法是什么?

问题2.为什么会这样?

<小时/> PS#1:

如果我将别名作为其他内容,问题就会消失。

即。 primary_key + 'AS id_',将输出:

[{
  id_: 42,
  product_number: 123,
  qty: 2
}]

<小时/> PS#2:

我发现包含PK也会起作用:

self.select(
    primary_key,
    primary_key + ' AS id', ...

输出:

[{
  xxx_id: 42,
  id: 42,
  product_number: 123,
  qty: 2
}]

但是,我必须后处理删除PK。

1 个答案:

答案 0 :(得分:3)

为什么会这样?

ActiveRecord:: AttributeMethods::Read读取属性值时,id是一种特殊情况:

def read_attribute(attr_name, &block)
  ...
  name = self.class.primary_key if name == "id".freeze
  _read_attribute(name, &block)
end

当您调用方法id时,ActiveRecord将获取主键xxx_id的值,只有在xxx_id语句中包含select时才能使用该值。< / p>

解决此问题的最简单方法是什么?

尝试覆盖ActiveRecord id逻辑可能会很危险,因为Rails代码和其他宝石可能依赖于它以这种方式工作。

如果您只需要返回值并且不一定需要使用ActiveRecord对象,则可以将select语句包装在select_all内:

class XXX < ActiveRecord::Base
  ...
  def self.get
    select(
      primary_key + ' AS id',
      'xxx_itmno AS product_number',
      'xxx_qty AS qty'
    )
  end

  def self.get_values
    connection.select_all(get)
  end

这将返回:

[{
  "id" => 42,
  "product_number" => 123,
  "qty" => 2
}]

如果您需要它们作为ActiveRecord对象,您可能需要加载没有别名的列,然后使用map之类的内容将它们转换为您想要的格式。