I know this was discussed a while back, but I couldn''t find the thread. Issue is that has_one associations don''t cache nils, whereas has_many do cache the empty array. Causes a big performance issue when you do things like: class People < ActiveRecord::Base has_one :thing end Person.find(:all, :include => :thing).each do |p| ...do something here with p.thing... end This results in lots of unnecessary and unexpected queries for all those people that don''t have things. So...is this intentional? Would core be open to a patch that allowed AR to differentiate between "nil -- this association needs to be loaded" and "nil -- the target is actually nil"?
Anyone? Michael A. Schoen wrote:> I know this was discussed a while back, but I couldn''t find the thread. > Issue is that has_one associations don''t cache nils, whereas has_many do > cache the empty array. > > Causes a big performance issue when you do things like: > > class People < ActiveRecord::Base > has_one :thing > end > > Person.find(:all, :include => :thing).each do |p| > ...do something here with p.thing... > end > > This results in lots of unnecessary and unexpected queries for all those > people that don''t have things. > > So...is this intentional? Would core be open to a patch that allowed AR > to differentiate between "nil -- this association needs to be loaded" > and "nil -- the target is actually nil"?
> So...is this intentional? Would core be open to a patch that allowed AR > to differentiate between "nil -- this association needs to be loaded" > and "nil -- the target is actually nil"?Yes, please do investigate something better. I believe it was done simply because it was easy at the time. -- David Heinemeier Hansson http://www.loudthinking.com -- Broadcasting Brain http://www.basecamphq.com -- Online project management http://www.backpackit.com -- Personal information manager http://www.rubyonrails.com -- Web-application framework
David Heinemeier Hansson wrote:>> So...is this intentional? Would core be open to a patch that allowed AR >> to differentiate between "nil -- this association needs to be loaded" >> and "nil -- the target is actually nil"? > > Yes, please do investigate something better. I believe it was done > simply because it was easy at the time.http://dev.rubyonrails.org/ticket/5757
On 8/8/06, Michael A. Schoen <schoenm@earthlink.net> wrote:> David Heinemeier Hansson wrote: > >> So...is this intentional? Would core be open to a patch that allowed AR > >> to differentiate between "nil -- this association needs to be loaded" > >> and "nil -- the target is actually nil"? > > > > Yes, please do investigate something better. I believe it was done > > simply because it was easy at the time. > > http://dev.rubyonrails.org/ticket/5757Good stuff, applied. Now to figure this out for eager associations... :) -- Rick Olson http://techno-weenie.net
This caused a breakage: http://dev.rubyonrails.org/ticket/5767 -Jonathan. On 8/9/06, Rick Olson <technoweenie@gmail.com> wrote:> On 8/8/06, Michael A. Schoen <schoenm@earthlink.net> wrote: > > David Heinemeier Hansson wrote: > > >> So...is this intentional? Would core be open to a patch that allowed AR > > >> to differentiate between "nil -- this association needs to be loaded" > > >> and "nil -- the target is actually nil"? > > > > > > Yes, please do investigate something better. I believe it was done > > > simply because it was easy at the time. > > > > http://dev.rubyonrails.org/ticket/5757 > > Good stuff, applied. Now to figure this out for eager associations... :) > > > -- > Rick Olson > http://techno-weenie.net > _______________________________________________ > Rails-core mailing list > Rails-core@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails-core >
Rick Olson wrote:> On 8/8/06, Michael A. Schoen <schoenm@earthlink.net> wrote: >> David Heinemeier Hansson wrote: >> >> So...is this intentional? Would core be open to a patch that >> allowed AR >> >> to differentiate between "nil -- this association needs to be loaded" >> >> and "nil -- the target is actually nil"? >> > >> > Yes, please do investigate something better. I believe it was done >> > simply because it was easy at the time. >> >> http://dev.rubyonrails.org/ticket/5757 > > Good stuff, applied. Now to figure this out for eager associations... :)I''ve just run into a problem with this. If you have a has_one with no associated object and try and access the association before saving, it dies when saving. Bit of an obscure explanation, let me illustrate it: Assuming the following (and an Account class to go with it) class Company < ActiveRecord::Base has_one :account end company = Company.new => <Company:.....> company.save => true company.account => nil company.save E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:123:in `send'' E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:123:in `method_missing'' E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/callbacks.rb:336:in `callback'' E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/callbacks.rb:335:in `callback'' E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/callbacks.rb:330:in `each'' E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/callbacks.rb:330:in `callback'' E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/callbacks.rb:243:in `create_or_update'' E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/base.rb:1489:in `save_without_validation'' E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/validations.rb:744:in `save_without_transactions'' E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/transactions.rb:120:in `save'' E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/transactions.rb:120:in `transaction'' E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/transactions.rb:86:in `transaction'' E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/transactions.rb:112:in `transaction'' E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/transactions.rb:120:in `save'' Attached is a diff containing a test for the associations tests which shows this behaviour. Thanks. _______________________________________________ Rails-core mailing list Rails-core@lists.rubyonrails.org http://lists.rubyonrails.org/mailman/listinfo/rails-core
I''d already mentioned this... http://dev.rubyonrails.org/ticket/5767 -Jonathan. On 8/13/06, Richard Livsey <richard@livsey.org> wrote:> > Rick Olson wrote: > > On 8/8/06, Michael A. Schoen <schoenm@earthlink.net> wrote: > >> David Heinemeier Hansson wrote: > >> >> So...is this intentional? Would core be open to a patch that > >> allowed AR > >> >> to differentiate between "nil -- this association needs to be > loaded" > >> >> and "nil -- the target is actually nil"? > >> > > >> > Yes, please do investigate something better. I believe it was done > >> > simply because it was easy at the time. > >> > >> http://dev.rubyonrails.org/ticket/5757 > > > > Good stuff, applied. Now to figure this out for eager associations... > :) > I''ve just run into a problem with this. If you have a has_one with no > associated object and try and access the association before saving, it > dies when saving. > > Bit of an obscure explanation, let me illustrate it: > > Assuming the following (and an Account class to go with it) > class Company < ActiveRecord::Base > has_one :account > end > > company = Company.new > => <Company:.....> > company.save > => true > > company.account > => nil > company.save > > > > E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:123:in > `send'' > > > E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:123:in > `method_missing'' > > > E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/callbacks.rb:336:in > `callback'' > > > E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/callbacks.rb:335:in > `callback'' > > > E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/callbacks.rb:330:in > `each'' > > > E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/callbacks.rb:330:in > `callback'' > > > E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/callbacks.rb:243:in > `create_or_update'' > > > E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/base.rb:1489:in > `save_without_validation'' > > > E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/validations.rb:744:in > `save_without_transactions'' > > > E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/transactions.rb:120:in > `save'' > > > E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/transactions.rb:120:in > `transaction'' > > > E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/transactions.rb:86:in > `transaction'' > > > E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/transactions.rb:112:in > `transaction'' > > > E:/rails/thatsprogress/config/../vendor/rails/activerecord/lib/active_record/transactions.rb:120:in > `save'' > > Attached is a diff containing a test for the associations tests which > shows this behaviour. > > Thanks. > > > Index: associations_test.rb > ==================================================================> --- associations_test.rb (revision 4721) > +++ associations_test.rb (working copy) > @@ -101,6 +101,14 @@ > assert_queries(0) { companies(:another_firm).account } > end > > + def test_saving_has_one_with_nil_value > + assert a = companies(:first_firm) > + a.account = nil > + assert a.save > + assert_equal nil, a.account > + assert a.save > + end > + > def test_proxy_assignment > company = companies(:first_firm) > assert_nothing_raised { company.account = company.account } > > > _______________________________________________ > Rails-core mailing list > Rails-core@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails-core > > >_______________________________________________ Rails-core mailing list Rails-core@lists.rubyonrails.org http://lists.rubyonrails.org/mailman/listinfo/rails-core
Jonathan Viney wrote:> I''d already mentioned this... > > http://dev.rubyonrails.org/ticket/5767 > > -Jonathan.Cool. Had a look on trac but didn''t see the ticket. Then again I have been up for 36hrs straight so I probably stared right at it and still didn''t see it! -- Richard Livsey http://livsey.org
If someone could apply this that would be fantastic. Patch attached. -Jonathan. On 8/13/06, Richard Livsey <richard@livsey.org> wrote:> > Jonathan Viney wrote: > > I''d already mentioned this... > > > > http://dev.rubyonrails.org/ticket/5767 > > > > -Jonathan. > > Cool. Had a look on trac but didn''t see the ticket. > Then again I have been up for 36hrs straight so I probably stared right > at it and still didn''t see it! > > -- > Richard Livsey > http://livsey.org > _______________________________________________ > Rails-core mailing list > Rails-core@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails-core >_______________________________________________ Rails-core mailing list Rails-core@lists.rubyonrails.org http://lists.rubyonrails.org/mailman/listinfo/rails-core