为什么组计算字段不会显示在查询结果中?

时间:2015-03-13 13:32:15

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

我有这样的查询: query = Link.select('url, max(created_at) as created_at, count(*) as url_count').group(:url).order('url_count desc, created_at asc')

query.results.first的示例结果:

2.2.0 :002 > query.first
 => #<Link id: nil, url: "http://1", created_at: "2015-03-10 16:43:54"> 

为什么这里没有url_count,即使我知道它是。

2.2.0 :003 > query.first.url_count
 => 17 

1 个答案:

答案 0 :(得分:5)

计数一直存在,但模型to_s方法并不知道。

当您的控制台从to_s记录结果时使用的query.first方法在activerecord中的某处定义,它使用在数据库中为模型定义的属性。由于您的属性仅针对此Link的特定实例定义,因此不适用于模型Link

我发现这非常有趣。以下是如何构建控制台中显示的消息的说明。它始于gem active_attr,下面显示了以下3种方法:

def inspect
  attribute_descriptions = attributes.sort.map { |key, value| "#{key}: #{value.inspect}" }.join(", ")
  separator = " " unless attribute_descriptions.empty?
  "#<#{self.class.name}#{separator}#{attribute_descriptions}>"
end

# ...

def attributes
  attributes_map { |name| send name }
end

# ...

def attributes_map
  Hash[ self.class.attribute_names.map { |name| [name, yield(name)] } ]
end

方法attributes_names在gem activerecord

中定义
def attribute_names
  @attribute_names ||= if !abstract_class? && table_exists?
      column_names
    else
      []
    end
end

# ...

def column_names
  @column_names ||= @connection.columns(@table_name).collect { |c| c.name }
end

这就是为什么你的计数没有出现的原因。

如果您真的希望它显示在您的控制台中,您可以覆盖inspect方法并将其添加到那里。