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

Mar*_*iwa 1 activerecord ruby-on-rails ruby-on-rails-4

我有这样的查询: 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"> 
Run Code Online (Sandbox Code Playgroud)

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

2.2.0 :003 > query.first.url_count
 => 17 
Run Code Online (Sandbox Code Playgroud)

Alb*_*bin 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
Run Code Online (Sandbox Code Playgroud)

该方法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
Run Code Online (Sandbox Code Playgroud)

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

如果你真的希望它出现在你的控制台中,你可以覆盖该inspect方法并将其添加到那里.