There has been a great deal of debate on how to extend Rails Associations. Ryan discusses the "block" method:
class Organization < ActiveRecord::Base
has_many :people do
def find_active
find(:all, :conditions => ["active = ?", true])
end
end
end
This is identical to the "extend" method; in fact Rails converts a "block" into an "extend":
module FindActiveExtension
def find_active
find(:all, :conditions => ["active = ?", true])
end
end
class Organization < ActiveRecord::Base
has_many :people, :extend => FindActiveExtension
end
The commenters then debate the merits of the "class method" method:
class Person < ActiveRecord::Base
def self.find_active
find(:all, :conditions => ["active = ?", true])
end
end
class Organization < ActiveRecord::Base
has_many :people
end
In all three cases (really two), you can call something like:
organization.people.find_active
There are differences, though! I ran some experiments to find out how each works, and found that unless you have some particular reason not to, you should always use the "block" or "extend" version, for two reasons:
- The "class method" version does not allow manual caching.
Will break, as Adam T. mentioned in the comments.class Person < ActiveRecord::Base def self.find_active @active ||= find(:all, :conditions => ["active = ?", true]) end end
-
The association version is slightly faster then the class version.
I created the same has_many relationship to two pairs of classes
(Person has_many Things; User has_many Widgets).
I then added 6 sub-association selectors (red, green, blue,
small, medium, large) in different ways:
Thing had class methods; User had the same methods embedded in
the has_many association. I then ran benchmarks on 100 users/people
and 5000 things/widgets (with identical respective associations).
The x1 times are for finding all of 6 sub-association lookups on
every Person (Class) and User (Association). The x2 times are
for finding and reloading all 6 (that is, to gain the benefit of
any automatic caching done by Rails or the database).
In absolute times:
user system total real Class (x1): 4.650000 0.680000 5.330000 ( 11.320903) Association (x1): 4.530000 0.670000 5.200000 ( 10.861711) Class (x2): 9.240000 1.360000 10.600000 ( 21.934539) Association (x2): 9.000000 1.330000 10.330000 ( 21.066327)
Dividing the bottom two rows in half:user system total real Class (x1): 4.650000 0.680000 5.330000 ( 11.320903) Association (x1): 4.530000 0.670000 5.200000 ( 10.861711) Class (x2)/2: 4.620000 0.680000 5.300000 ( 10.967270) Association (x2)/2: 4.500000 0.665000 5.165000 ( 10.533164)
Dividing all rows by the number of queries performed (per/query time):user system total real Class (x1)/600: 0.007750 0.001133 0.008883 ( 0.018868) Association (x1)/600: 0.007550 0.001117 0.008667 ( 0.018103) Class (x2)/1200: 0.007700 0.001133 0.008833 ( 0.018279) Association (x2)/1200: 0.007500 0.001108 0.008608 ( 0.017555)
The association version is a little faster, and gains more from the automatic caching Rails does.
You can check out the experiment at https://svn.u-presence.com/svn/experiments/association_vs_class/ (username guest, no password).
4 comments:
Yes undoubtedly, in some moments I can phrase that I jibe consent to with you, but you may be inasmuch as other options.
to the article there is even now a definitely as you did in the fall efflux of this request www.google.com/ie?as_q=webcam zone trigger pro 2.11 ?
I noticed the axiom you have not used. Or you use the black methods of development of the resource. I take a week and do necheg
Amiable dispatch and this fill someone in on helped me alot in my college assignement. Thank you for your information.
Wow, nice post,there are many person searching about that now they will find enough resources by your post.Thank you for sharing to us.Please one more post about that..
Wonderful post. If only I'd of come across something as wise and straightforward when I was starting out! See you at the reading!
Post a Comment