Pros/cons of using ActiveRecord select() to create temporary attributes

342 views
Skip to first unread message

James Ferguson

unread,
Jul 8, 2012, 10:26:56 PM7/8/12
to rails-oceania
Hi,

I recently found a way to do with Active Record queries something I'd
previously done in other languages a lot, which was aggregations and
simple calculations or IF() statements in the SELECT clause aliased to
a column name. It turns out Active Record allows this and adds
temporary attributes to the models that come back from the query. An
example use might be to do multiple counts with a single query.

My question is simply: Is this a good practice? Why or why not?

There's more details on the Stack Overflow question
(http://stackoverflow.com/questions/11354469/pros-cons-of-using-activerecord-select-to-create-temporary-attributes).

Thanks,

James

Ben Hoskings

unread,
Jul 9, 2012, 4:11:32 AM7/9/12
to rails-...@googlegroups.com
Interesting question; I think it depends on how you're using them.

If it's a one-off aggregation that's used within the method that queries it, and the logic is clear (and specced), then I think it's fine.

On the other hand, if the aggregation is a value that you'd like to use more widely, I'd define an explicit helper method for it, to return just a list of the aggregated values, instead of a list of records with the extra field.

Alternatively, you could create a new model and back it onto a DB view, that presents the aggregation at the DB level. That way, the aggregated field appears as a normal (albeit readonly) model attribute.

- Ben
> --
> You received this message because you are subscribed to the Google Groups "Ruby or Rails Oceania" group.
> To post to this group, send email to rails-...@googlegroups.com.
> To unsubscribe from this group, send email to rails-oceani...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/rails-oceania?hl=en.
>

Brad Wilson

unread,
Jul 9, 2012, 6:06:55 PM7/9/12
to rails-...@googlegroups.com
I think that example 4 on the grayproductions website is a pretty good
example of when you might want to do this. We use that technique in
some reports already, and it makes a lot of sense there - why not just
ask the db for all the data you want at once?

I have a few concerns though:
- is all the logic about what it means to be "viewed" tied up in
that select? Do we have to duplicate it in a scope? What if we want to
get some_profile.viewed.last ?
- what if we only want 1 of those counts at a time? Or all of them,
plus some more?

I know those issues can be worked around, but the workarounds I can
think of seem kind of clunky.

When James and I first talked about this, I thought he was suggesting
adding a select as a default scope to a model, then using that to
replace a normal method (including the view count every single time we
loaded a profile, or something similar). So my initial impression is
that you were looking for semi-permanent attributes rather than
temporary. Sorry about the mixup.

I still think that kind of default scope stuff would would be
trickiness without a real payoff, but if it's a one-off, :select makes
sense.
Reply all
Reply to author
Forward
0 new messages