Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Related Models #2

Open
mbleigh opened this issue Sep 1, 2011 · 3 comments
Open

Support Related Models #2

mbleigh opened this issue Sep 1, 2011 · 3 comments

Comments

@mbleigh
Copy link

mbleigh commented Sep 1, 2011

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
Copy link
Owner

ernie commented Sep 2, 2011

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?

@mbleigh
Copy link
Author

mbleigh commented Sep 2, 2011

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
Copy link
Owner

ernie commented Sep 2, 2011

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants