I have query like this:
query = Link.select('url, max(created_at) as created_at, count(*) as url_count').group(:url).order('url_count desc, created_at asc')
Sample results of query.results.first
:
2.2.0 :002 > query.first
=> #<Link id: nil, url: "http://1", created_at: "2015-03-10 16:43:54">
Why there is no url_count
here, even though I know it is.
2.2.0 :003 > query.first.url_count
=> 17
The count is there all along but the model to_s
method does not know about it.
The to_s
method which is used when your console logs the result from query.first
is defined somewhere in activerecord and it uses the attributes defined for the model in the database. Since your attribute is only defined for this particular instance of Link
not for the model Link
.
I found this quite interesting. Below is a description of how the message displayed in your console is constructed. It starts out in the gem active_attr
with these 3 methods displayed below:
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
the method attributes_names
is defined in the 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
And that is why your count does not show up.
If you really want it to show up in your console you could override the inspect
method and add it there.