Help with counter_cache

I have two models:

Items
-id
-name
-created_by (links to user id)

Users
-id
-name
-items_count

item.rb:
belongs_to :user, :class_name => ‘User’, :foreign_key => ‘created_by’,
:counter_cache => true

user.rb:
has_many :items, :foreign_key => ‘created_by’


is this all i need to have it increment the User.items_count field
everytime a new item is created? I’m not getting any error messages but
it’s not updating the field.

can someone shed some light?

bah…i figured it out. i didn’t have a default value of 0 set in the
field so it wasn’t updating. now it’s working!

the only thing now is that i have a couple thousand users who have 0 for
the count values. what do you think is the best way i can mass update
this field?

Bryce R. wrote:

You can run a migration like this

def self.up
User.find(:all) do |u|
u.update_attribute :items_count, s.items.count
end
end

That will go through all your users and update the items_count field
for all of them.

Bryce R.
[ twitter ][ blog ][ myspace ][ facebook ]

thanks for the quick response!

i just ran it but it didn’t seem to update anything.

just curious what is the ‘s’ for in s.items.count?

You can run a migration like this

def self.up
User.find(:all) do |u|
u.update_attribute :items_count, s.items.count
end
end

That will go through all your users and update the items_count field
for all of them.

Bryce R.
[ twitter ][ blog ][ myspace ][ facebook ]

Oh sorry! I was copying the code out of a project I had.

change s.items.count to u.items.count

– Bryce R.

Bryce R. wrote:

You can run a migration like this

def self.up
User.find(:all) do |u|
u.update_attribute :items_count, s.items.count
end
end

That will go through all your users and update the items_count field
for all of them.

Bryce R.
[ twitter ][ blog ][ myspace ][ facebook ]

i think i found the main issue. I think there is supposed to be an each
in there like:

def self.up
User.find(:all).each do |u|
u.update_attribute :items_count, u.items.count
end
end

the weird thing is that now the migration is taking 8 seconds so it
looks promising but the data is still not updated! if i change
u.items.count to a constant like 1 it works fine, but it’s not give me
error messages and @user.items.count works in my views so i’m not sure
what’s wrong!

ah well, i guess i’ll take another look at it tomorrow morning. thanks
for the help so far! hopefully someone can see my silly mistake.

Bryce R. wrote:

Oh sorry! I was copying the code out of a project I had.

change s.items.count to u.items.count

– Bryce R.

np!

i just tried it with the new code and it says its successful again but
items_count is still showing 0. i checked @user.items.count in one of
my views and that works fine…must be something small. here is my
output of the migration:

skulik@kuliksco-ub:/u1/app/wldev$ rake db:migrate
(in /u1/app/wldev)
== 20081218000000 UpdateItemsCount: migrating

== 20081218000000 UpdateItemsCount: migrated (0.1271s)

skulik@kuliksco-ub:/u1/app/wldev$ cat
db/migrate/20081218000000_update_items_count.rb
class UpdateItemsCount < ActiveRecord::Migration

def self.up
User.find(:all) do |u|
u.update_attribute :items_count, u.items.count
end
end

end

Sazima wrote:

Maybe s.items.count is zero?

Cheers, Sazima

On Dec 19, 5:01�am, Scott K. [email protected]

hmm…it shouldn’t be since @user.items.count in my view shows the count
correctly for each user.

Maybe s.items.count is zero?

Cheers, Sazima

On Dec 19, 5:01 am, Scott K. [email protected]

Scott K. wrote:

Sazima wrote:

Maybe s.items.count is zero?

Cheers, Sazima

On Dec 19, 5:01�am, Scott K. [email protected]

hmm…it shouldn’t be since @user.items.count in my view shows the count
correctly for each user.

is there another i can do it like this but not using a migration?

i tried to create a rake task but that didn’t work. here is my rake
task:

skulik@kuliksco-ub:/u1/app/wldev/lib/tasks$ cat update_items_count.rake
task :updateItemsCount do
User.find(:all) do |u|
u.update_attribute :items_count, s.items.count
end
end

skulik@kuliksco-ub:/u1/app/wldev/lib/tasks$ rake updateItemsCount
(in /u1/app/wldev)
rake aborted!
uninitialized constant User

(See full trace by running task with --trace)

thanks!

Scott K. wrote:

Scott K. wrote:

Scott K. wrote:

Sazima wrote:

Maybe s.items.count is zero?

Cheers, Sazima

On Dec 19, 5:01�am, Scott K. [email protected]

hmm…it shouldn’t be since @user.items.count in my view shows the count
correctly for each user.

is there another i can do it like this but not using a migration?

i tried to create a rake task but that didn’t work. here is my rake
task:

skulik@kuliksco-ub:/u1/app/wldev/lib/tasks$ cat update_items_count.rake
task :updateItemsCount do
User.find(:all) do |u|
u.update_attribute :items_count, s.items.count
end
end

skulik@kuliksco-ub:/u1/app/wldev/lib/tasks$ rake updateItemsCount
(in /u1/app/wldev)
rake aborted!
uninitialized constant User

(See full trace by running task with --trace)

thanks!

got it. i had to do this:

task(:updateItemsCount => :environment) do
User.find(:all).each do |u|
u.update_attribute :items_count, u.items.count
end
end

it’s still not working but at least i can test easier!

finally got the item count updated! 4 hours on this to realize i needed
to remove

:counter_cache => true

since i think it was protecting the items_count field from being
updated.

Scott K. wrote:

Scott K. wrote:

Sazima wrote:

Maybe s.items.count is zero?

Cheers, Sazima

On Dec 19, 5:01�am, Scott K. [email protected]

hmm…it shouldn’t be since @user.items.count in my view shows the count
correctly for each user.

is there another i can do it like this but not using a migration?

i tried to create a rake task but that didn’t work. here is my rake
task:

skulik@kuliksco-ub:/u1/app/wldev/lib/tasks$ cat update_items_count.rake
task :updateItemsCount do
User.find(:all) do |u|
u.update_attribute :items_count, s.items.count
end
end

skulik@kuliksco-ub:/u1/app/wldev/lib/tasks$ rake updateItemsCount
(in /u1/app/wldev)
rake aborted!
uninitialized constant User

(See full trace by running task with --trace)

thanks!

got it. i had to do this:

task(:updateItemsCount => :environment) do
User.find(:all).each do |u|
u.update_attribute :items_count, u.items.count
end
end

it’s still not working but at least i can test easier!