Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Support Related Models #2

Open
mbleigh opened this Issue September 01, 2011 · 3 comments

2 participants

Michael Bleigh Ernie Miller
Michael Bleigh

I was going to just write a patch myself but the code is a little more involved that I expected. This would be super-amazing if you could include fields from included related models. For example, if had a Message model that belonged to a user, I'd love to be able to do something like:

messages.includes(:user)[{user: :name}, :text]

This would give me the name field from the User model and the text field from the Message model. I'd even be happy just to take SQL-style table dot notation:

messages.includes(:user)['users.name', :text]

What do you think?

Ernie Miller
Owner

At first glance, this sounds really cool!

In practice, though, I wonder how much of the speed gain will end up getting lost as the extra complexity is layered in, and I worry a bit about the complexity it adds for the user, as well.

For a simple belongs_to association, like the one you just showed, it makes some sense. For has_many associations, what would the desired behavior be? Return an array inside an array? Duplicate the columns from the parent table and return a separate row for each has_many item, to keep the array structure flat?

Since the whole intention is to avoid instantiation of the ActiveRecord objects, it seems as though at the very minimum it'd require the use of the old "includes-dependent where" (t0.r0, t1.r0, etc.) code to do joins for the associated objects.

I just wonder if your need wouldn't be better served by using the existing methods available for arrays:

people = Person.where('last_name like "Number1%"')[:id, :last_name]
widgets = Widget.where(:person_id => people.map(&:first))[:person_id, :name]
people.map! {|p| p + widgets.assoc(p.first)[1..-1]}
# or...
(people + widgets).group_by(&:first).values.map!(&:flatten).each do |id, last_name, _, name|
  puts "#{id} #{last_name} #{name}"
end

If it wouldn't, then maybe the extra overhead of ActiveRecord is justified, to handle the association logic?

Michael Bleigh

Hmm...hadn't thought of it for anything but belongs_to relationships. That's not a bad point. At the same time, though, I think it would still save a LOT of overhead if you could do it in some fashion with joins. Imagine I have that chat example and all I'm trying to do is print out a chat log of hundreds, maybe thousands of messages. The overhead for the objects would be massive compared to the value and your solution, while certainly feasible, is a bit messy.

I can understand the challenges but if you ever figure out a relatively simple way to do it, even in a limited fashion, let me know. :)

Ernie Miller
Owner

I think you're being too kind by saying my solution is a "bit" messy. :) But yeah, it's a bit tricky to dig in and grab the AR association goodies and skip the objects without adding too much weight. Will definitely keep it in mind.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.