I''m trying to ensure that I keep the number of queries down a bit. If I have two model (lets call them Foo and Bar). They have a many to many relationship. Now I want to get (and paginate) records from Bar that are related to a certain record in Foo. For example I want all records from Bar whose name starts with ''C'' and are related to record Foo whose name is ''Baz''. Now it seems that I should be able to do this with just one query that returns just the records I want. In another framework I use (in Perl) I would do this like: @bars = search Bar(''Name STARTS WITH C'', ''Foo.Name = Baz''); How do I do this in Rails? Eric _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Nov 4, 2005, at 9:15 PM, Eric Anderson wrote:> I''m trying to ensure that I keep the number of queries down a bit. > If I have two model (lets call them Foo and Bar). They have a many > to many relationship. Now I want to get (and paginate) records from > Bar that are related to a certain record in Foo. For example I want > all records from Bar whose name starts with ''C'' and are related to > record Foo whose name is ''Baz''. Now it seems that I should be able > to do this with just one query that returns just the records I > want. In another framework I use (in Perl) I would do this like: > > @bars = search Bar(''Name STARTS WITH C'', ''Foo.Name = Baz''); > > How do I do this in Rails?Assuming Foo has_and_belongs_to_many :bars, Foo.find_by_name(''Baz'').bars.find(:conditions => [''name starts with ?'', c]) This is two select queries. You can use Bar.find_by_sql to reduce it to one query, but that''s missing the productivity sweet spot in favor of an unmeasured benefit. jeremy -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2 (Darwin) iD8DBQFDbE6iAQHALep9HFYRAqntAKCoVLhSBBItrBHw0Q2SuF+P0tmGFQCfdFdg fEx/+iJYHzdKf/UDvNUn0aU=Xskr -----END PGP SIGNATURE-----
Something like this should work: @foo = Foo.find_by_name(''Baz'', :include => :bars, :conditions => ''bars.name LIKE ''%C'') then you''d access them as @foo.bars, which would give you an array of all the bars. This obviously depends on you having set up the correct habtm association in the foo & bar models. You can look under eager loading in ActiveRecord::Associations::ClassMethods for more details. Luke
Luke Randall wrote:> @foo = Foo.find_by_name(''Baz'', :include => :bars, :conditions => > ''bars.name LIKE ''%C'')This is great. I didn''t know I could use eager associations in this way.> You can look under eager loading in > ActiveRecord::Associations::ClassMethods for more details.I looked at this documentation and I saw this: ****** START DOCS ******* Please note that limited eager loading with has_many and has_and_belongs_to_many associations is not compatible with describing conditions on these eager tables. This will work: Post.find(:all, :include => :comments, :conditions => "posts.title = ''magic forest''", :limit => 2) …but this will not (and an ArgumentError will be raised): Post.find(:all, :include => :comments, :conditions => "comments.body like ''Normal%''", :limit => 2) ******* END DOCS ******** But it doesn''t say why this is the case. It looks like they should both work! Eric _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails