Join GitHub today
Incorrect attribute/column type fetched for a group by column on an associated table #30476
I've just encountered an interesting edge case that breaks grouped count queries in ActiveRecord.
Background: I'm currently in the process of migrating tables from integer to uuid primary keys in my postgresql db. As a result, some tables have an id of integer, and others have an id of uuid. In the following example, Note has a uuid id, and Organization has an integer id. If I execute the following query (simplified from my actual usage, but enough to demonstrate the issue):
I'll get a result of something like
The reason is, when
The typecast of the integer Organization id to a uuid results in
My current quick fix solution is to assume any column names with a . in it are references to model tables, and to check the type on that model:
There's clearly ways that this can also break, and not the most optimal code (splitting the string multiple times, etc), so I didn't think it was necessarily a good solution to submit a pull request for, but this monkey patch gets my code working for now, and I suspect the maintainers will have better ideas...!
Any chance you could link to a gist with an executable test case in this format: https://github.com/rails/rails/blob/master/guides/bug_report_templates/active_record_master.rb
I have this exact same bug. It will happen for every group on joined table where both tables have a column with the same name but a different type.
Thanks @francisli for pointing it out. I can confirm that your monkey patch would break some implementations: the argument passed to
# count posts per day Post.group("date_trunc('day', CAST(posts.created_at as timestamp))").count
In this case it would try to
def type_for(field, &block) field_name = field.respond_to?(:name) ? field.name.to_s : field.to_s.split(".").last if field.include?('.') && (field.to_s.split('.').first.classify.constantize rescue false) field.to_s.split('.').first.classify.constantize.type_for_attribute(field_name, &block) else @klass.type_for_attribute(field_name, &block) end end
This issue has been automatically marked as stale because it has not been commented on for at least three months.