views:

152

answers:

2

Hello! I have three models, User, Type and TypeDescription, and as you can see below, each User may have many types, but each type has only one description. So as optimization, I thought each TypeDescription should be joined with Type via JOIN in sql, so I used default_scope and defined join, and that works when I get type via Type.find( id ), but when I use user = User.find( 1 ), each type in user.types doesn't have data from TypeDescription, because default_scope just adds defined options to methods like find, all etc. So what I'm looking for is solution to have this work in my situation, so what I want is, when I get certain or all users, I want to have all User's types and each type should have data from TypeDescription.

so, code is:

class User
  has_many :types
end

class Type
  has_one :type_description

  default_scope :joins => :type_description
end

class TypeDescription
  belongs_to :type
end

Thanks!

+1  A: 

if you want to have the TypeDescription with the Type, you need to use :include, not :joins

amikazmi
but it's faster if I JOIN TypeDescription to each Type, in both situations, there are two queries, but join is faster than two separate queries...
mfolnovich
so, what I want is to generate two queries when I try User.find( 1, :include => [ :types ] ) SELECT * FROM users WHERE id = 1; SELECT * FROM types JOIN type_descriptions ON types.id = type_descriptions.id WHERE `id` IN ( 1, 3, 5 );
mfolnovich
you do User.find( 1, :include => { :types => :type_descriptions } )it'll generate 3 queries, and it's ok... all you want to do is optimize the N+1 queries to 3, 3 is low enough :)
amikazmi
but I think that could be even better because type has one type_description, not many of them, so joins could be used somehow... I guess I'll have to write query as finder_sql ...
mfolnovich
just a tip- this is premature optimization... don't waste your time on it :)
amikazmi
+1  A: 

Since rails 2.1, the "include" has changed to generate multiple query instead of just one query. The reason is that for large table, a join can produce lots of duplicated rows, which puts the overhead on the rails.

here is a good article to find more info. In your one-to-one situation, if you still want "include" to perform "join", the article did mention there is a filtering option but i can't find it myself.

either way, amikazmi is right, performance wise, it probably does not matter for now.

ez