On Jan 14, 2011, at 6:02 AM, IAmNan wrote: > Wait, that can't really happen where I thought it could. > > It seems like sum etc. should optionally take a hash for the first > parameter, as in table => column: > BlogPost.sum(:user => :old_accounts_id, :group => > 'blog_posts.id').first > > The resultant SQL would start out with: > SELECT SUM(users.old_accounts_id) AS sum_old_accounts_id... > > This syntax would allow us to assume :joins => :user, unless :includes > => :user was added. > > The table and column would be available to get the correct type. > > There is the possibility of identically named columns in two or more > tables, right? So, without something like this, AR is just hoping the > database will figure out which column to sum anyway.
That's my take yeah. After the call Rails could look at all the tables involved and if it finds one and only one match, cast it. If it finds multiple, don't touch it, but I doubt that will ever happen as the database should have already freaked out about that case... > On Jan 14, 9:30 am, IAmNan <[email protected]> wrote: >> It turns out Philip and I were drafting our posts at the same time, >> which is why they might sound redundant. >> >> Matt, I'm using Rail 3.0.3 but was looking in the same file as you. >> Perhaps the correct return type could be inferred if the aliased >> column name was constructed to include the type, in addition to the >> column and function names. In Philip's example it would change from: >> sum_old_accounts_id >> ...to... >> sum_old_accounts_id_integer >> >> That seems pretty deterministic, yes? >> >> On Jan 13, 6:15 pm, Matt Jones <[email protected]> wrote: >> >> >> >> >> >> >> >>> On Jan 13, 12:51 pm, Philip Hallstrom <[email protected]> wrote: >> >>>> Interesting. I don't think AR will ever get the right data types since it >>>> has no idea what "sum_quantity" should translate to. In Rails 3, >>>> Postgresql 9.x I have User and BlogPost. Users have many blog posts. Use >>>> also has an 'old_accounts_id' which is an integer and we'll use for >>>> summing... I think this matches your setup... >> >>>> ruby-1.8.7-p330 :023 > BlogPost.sum(:old_accounts_id, :joins => :user, >>>> :group => 'blog_posts.id').first >> >>>> SQL (3.8ms) SELECT SUM(old_accounts_id) AS sum_old_accounts_id, >>>> blog_posts.id AS blog_posts_id FROM "blog_posts" INNER JOIN "users" ON >>>> "users"."id" = "blog_posts"."user_id" GROUP BY blog_posts.id >> >>>> => [5603, "0"] >> >>>> ruby-1.8.7-p330 :024 > User.sum(:old_accounts_id, :joins => :blog_posts, >>>> :group => 'blog_posts.id').first >> >>>> SQL (5.0ms) SELECT SUM("users"."old_accounts_id") AS >>>> sum_old_accounts_id, blog_posts.id AS blog_posts_id FROM "users" INNER >>>> JOIN "blog_posts" ON "blog_posts"."user_id" = "users"."id" GROUP BY >>>> blog_posts.id >> >>>> => [5603, 0] >> >>>> Note that by switching the query around so I run the query on the model >>>> I'm summing and join the other one I get back integers. >> >>>> The only difference that I can think of is that in the former AR knows >>>> about 'BlogPost' and 'sum_old_accounts_id' and even with it's magic can't >>>> relate the two. In the latter (i'm guessing, haven't checked the code) >>>> that it knows 'User' and 'sum_old_accounts_id'. It knows that it called >>>> 'sum' to turns it into 'old_accounts_id' which it knows is a field of User >>>> so type casts it. >> >>>> Maybe. Would be interesting to dig into the source and see.... >> >>> You've pretty much hit it on the head - digging into the 2.3.10 source >>> (what I've got handy) shows the code calling column_for on the given >>> name, which will *only* return a column object if it's a field on the >>> model you called .sum on. That column is then used to cast the result >>> to the correct type. [lines 241-312 in calculations.rb, 2.3.10 >>> version] >> >>> The SQlite3 issue is a red herring - there's a whole different typing >>> mechanism in play there:http://www.sqlite.org/datatype3.html >> >>> It might be a worthwhile patch to try looking up the column in the >>> *right* table, but that's only going to be obvious when the name is >>> qualified (:'users.old_account_id') instead of just :old_account_id >>> (allowed by SQL, if it's not ambiguous). >> >>> --Matt Jones > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Talk" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/rubyonrails-talk?hl=en. > -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.

