Stephen Bannasch
2008-Oct-10 20:17 UTC
problem writing to a counter_cache with update_attribute
I added a counter_cache to an existing parent-child model pair and wanted to set all the values for the counter_cache but can''t do it using update_attribute (or a number of other methods). Should I create a bug report? I created a simple test app in 2.2.1 to isolate the problem. # create the learner and learner_session models and migrations: script/generate model learner name:string learner_session_id:integer script/generate model learner_session learner_id:integer rake db:migrate # add the associations to the models: class Learner < ActiveRecord::Base has_many :learner_sessions end class LearnerSession < ActiveRecord::Base belongs_to :learner end # create a learner and 2 learner sessions without a counter_cache $ script/console>> l = Learner.create(:name => "stephen")=> #<Learner id: 1, name: "stephen", learner_session_id: nil>>> l.learner_sessions.create=> #<LearnerSession id: 1, learner_id: 1>>> l.learner_sessions.create=> #<LearnerSession id: 2, learner_id: 1>>> l.learner_sessions.count=> 2 # now run this migration: class AddCounterCacheToLearners < ActiveRecord::Migration def self.up add_column :learners, :learner_sessions_count, :integer, :default => 0 # Learner.reset_column_information end def self.down remove_column :learners, :learner_sessions_count end end # and add the counter_cache to the belongs_to association class LearnerSession < ActiveRecord::Base belongs_to :learner, :counter_cache => true end # back into script/console $ script/console>> l = Learner.find(:first)=> #<Learner id: 1, name: "stephen", learner_session_id: nil, learner_sessions_count: 0> # there are still 2 learner sessions:>> l.learner_sessions.count=> 2 # but the learner_sessions_count is not set yet:>> l.learner_sessions_count=> 0 # update the learner_sessions_count:>> l.update_attribute(:learner_sessions_count, 2)=> true # it is written to the model object:>> l=> #<Learner id: 1, name: "stephen", learner_session_id: nil, learner_sessions_count: 2>>> l.learner_sessions_count=> 2 # but not to the database>> l = Learner.find(:first)=> #<Learner id: 1, name: "stephen", learner_session_id: nil, learner_sessions_count: 0> --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
Frederick Cheung
2008-Oct-11 00:27 UTC
Re: problem writing to a counter_cache with update_attribute
On 10 Oct 2008, at 21:17, Stephen Bannasch wrote:> > I added a counter_cache to an existing parent-child model pair and > wanted to set all the values for the counter_cache but can''t do it > using update_attribute (or a number of other methods). > > Should I create a bug report? >From the docs (http://api.rubyonrails.com/classes/ActiveRecord/Associations/ClassMethods.html ):> Note: Specifying a counter cache will add it to that model‘s list of > readonly attributes using attr_readonly.Fred>--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
Duncan Beevers
2008-Oct-11 01:03 UTC
Re: problem writing to a counter_cache with update_attribute
I''m sure you read Frederick''s response about the counter_cache being readonly. The way to properly populate these during a migration is to redeclare the Learner class as an inner-class of the Migration itself, specifying only minimal functionality. class AddCounterCacheToLearners < ActiveRecord::Migration class Learner < ActiveRecord::Base def reset_column_information # re-implement reset_column_information functionality here end end def self.up add_column :learners, :learner_sessions_count, :integer, :default => 0 Learner.reset_column_information end def self.down remove_column :learners, :learner_sessions_count end end On Fri, Oct 10, 2008 at 1:17 PM, Stephen Bannasch < stephen.bannasch@deanbrook.org> wrote:> > I added a counter_cache to an existing parent-child model pair and > wanted to set all the values for the counter_cache but can''t do it > using update_attribute (or a number of other methods). > > Should I create a bug report? > > I created a simple test app in 2.2.1 to isolate the problem. > > # create the learner and learner_session models and migrations: > > script/generate model learner name:string learner_session_id:integer > script/generate model learner_session learner_id:integer > rake db:migrate > > # add the associations to the models: > > class Learner < ActiveRecord::Base > has_many :learner_sessions > end > > class LearnerSession < ActiveRecord::Base > belongs_to :learner > end > > # create a learner and 2 learner sessions without a counter_cache > > $ script/console > > >> l = Learner.create(:name => "stephen") > => #<Learner id: 1, name: "stephen", learner_session_id: nil> > > >> l.learner_sessions.create > => #<LearnerSession id: 1, learner_id: 1> > > >> l.learner_sessions.create > => #<LearnerSession id: 2, learner_id: 1> > > >> l.learner_sessions.count > => 2 > > # now run this migration: > > class AddCounterCacheToLearners < ActiveRecord::Migration > def self.up > add_column :learners, :learner_sessions_count, :integer, :default => 0 > # Learner.reset_column_information > end > > def self.down > remove_column :learners, :learner_sessions_count > end > end > > # and add the counter_cache to the belongs_to association > > class LearnerSession < ActiveRecord::Base > belongs_to :learner, :counter_cache => true > end > > # back into script/console > > $ script/console > > >> l = Learner.find(:first) > => #<Learner id: 1, name: "stephen", learner_session_id: nil, > learner_sessions_count: 0> > > # there are still 2 learner sessions: > > >> l.learner_sessions.count > => 2 > > # but the learner_sessions_count is not set yet: > > >> l.learner_sessions_count > => 0 > > # update the learner_sessions_count: > > >> l.update_attribute(:learner_sessions_count, 2) > => true > > # it is written to the model object: > > >> l > => #<Learner id: 1, name: "stephen", learner_session_id: nil, > learner_sessions_count: 2> > > >> l.learner_sessions_count > => 2 > > # but not to the database > > >> l = Learner.find(:first) > => #<Learner id: 1, name: "stephen", learner_session_id: nil, > learner_sessions_count: 0> > > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
Stephen Bannasch
2008-Oct-11 04:25 UTC
problem writing to a counter_cache with update_attribute
Thanks Frederic and Duncan, FYI: here''s the complete migration for the simple test case that adds a counter_cache AND sets the value. class AddCounterCacheToLearners < ActiveRecord::Migration class Learner < ActiveRecord::Base has_many :learner_sessions def reset_column_information # re-implement reset_column_information functionality here generated_methods.each { |name| undef_method(name) } @column_names = @columns = @columns_hash = @content_columns = @dynamic_methods_hash = @generated_methods = @inheritance_column = nil end end def self.up add_column :learners, :learner_sessions_count, :integer, :default => 0 Learner.reset_column_information Learner.find(:all).each do |learner| count = learner.learner_sessions.count learner.update_attribute(:learner_sessions_count, count) end end def self.down remove_column :learners, :learner_sessions_count end end --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
Damian Janowski
2008-Oct-12 22:47 UTC
Re: problem writing to a counter_cache with update_attribute
On Sat, Oct 11, 2008 at 1:25 AM, Stephen Bannasch <stephen.bannasch@deanbrook.org> wrote:> > Thanks Frederic and Duncan, > > FYI: here''s the complete migration for the simple test case that adds > a counter_cache AND sets the value.Or you could use http://rails.lighthouseapp.com/projects/8994/tickets/228 :-) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
Stephen Bannasch
2008-Oct-13 19:39 UTC
problem writing to a counter_cache with update_attribute
At 7:47 PM -0300 10/12/08, Damian Janowski wrote:>On Sat, Oct 11, 2008 at 1:25 AM, Stephen Bannasch ><stephen.bannasch@deanbrook.org> wrote: >> >> Thanks Frederic and Duncan, >> >> FYI: here''s the complete migration for the simple test case that adds >> a counter_cache AND sets the value. > >Or you could use http://rails.lighthouseapp.com/projects/8994/tickets/228 :-)Thanks for that pointer Damian. I didnm''t know about the class method Model.update_counters. I''ve simplified my migration as follows: class AddCounterCacheToLearners < ActiveRecord::Migration def self.up add_column :learners, :learner_sessions_count, :integer, :default => 0 Learner.reset_column_information Learner.find(:all).each do |learner| change_in_count = learner.learner_sessions.count - learner.learner_sessions_count Learner.update_counters(learner.id, :learner_sessions_count => change_in_count) end end def self.down remove_column :learners, :learner_sessions_count end end While this is better than my previous solution it still seems a bit ugly. I like your proposed patch but it''s marked as "wontfix". In my simplified migration above this section: Learner.reset_column_information Learner.find(:all).each do |learner| change_in_count = learner.learner_sessions.count - learner.learner_sessions_count Learner.update_counters(learner.id, :learner_sessions_count => change_in_count) end is equivalent to the suggestions at the end of your patch discussion for a class method something like this: Learner.update_counter_cache --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
Trevor Turk
2008-Oct-14 18:44 UTC
Re: problem writing to a counter_cache with update_attribute
On Oct 13, 2:39 pm, Stephen Bannasch <stephen.banna...@deanbrook.org> wrote:> I like your proposed patch but it''s marked as "wontfix". > http://rails.lighthouseapp.com/projects/8994/tickets/228I like some of the ideas here, and I''ve been annoyed by this issue quite a few times. Did a new ticket get created, or was a consensus about an approach reached? - Trevor --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
Damian Janowski
2008-Oct-14 19:50 UTC
Re: problem writing to a counter_cache with update_attribute
On Tue, Oct 14, 2008 at 4:44 PM, Trevor Turk <trevorturk@gmail.com> wrote:> > On Oct 13, 2:39 pm, Stephen Bannasch <stephen.banna...@deanbrook.org> > wrote: > >> I like your proposed patch but it''s marked as "wontfix". >> http://rails.lighthouseapp.com/projects/8994/tickets/228 > > I like some of the ideas here, and I''ve been annoyed by this issue > quite a few times. Did a new ticket get created, or was a consensus > about an approach reached?No consensus :-/ I think the resolution was "we don''t want yet another migration helper" (?). --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
I like the idea of adding a class method like Model.reset_counter_cache(:column_name) I don''t think there is a new ticket. On Tue, Oct 14, 2008 at 9:50 PM, Damian Janowski <damian.janowski@gmail.com> wrote:> > On Tue, Oct 14, 2008 at 4:44 PM, Trevor Turk <trevorturk@gmail.com> wrote: >> >> On Oct 13, 2:39 pm, Stephen Bannasch <stephen.banna...@deanbrook.org> >> wrote: >> >>> I like your proposed patch but it''s marked as "wontfix". >>> http://rails.lighthouseapp.com/projects/8994/tickets/228 >> >> I like some of the ideas here, and I''ve been annoyed by this issue >> quite a few times. Did a new ticket get created, or was a consensus >> about an approach reached? > > No consensus :-/ > > I think the resolution was "we don''t want yet another migration helper" (?). > > > >-- Cheers! - Pratik http://m.onkey.org --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
Trevor Turk
2008-Oct-14 21:19 UTC
Re: problem writing to a counter_cache with update_attribute
On Oct 14, 3:21 pm, Pratik <pratikn...@gmail.com> wrote:> I like the idea of adding a class method like > Model.reset_counter_cache(:column_name) > > I don''t think there is a new ticket.I like that as well. I made a new ticket: http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/1211-reset_counter_cache This is probably something I can work on, unless somebody else is chomping at the bit. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---