This project is archived and is in readonly mode.
counter_cache doesn't update when :order specified on has_many association
Reported by subimage | October 7th, 2009 @ 08:37 PM
When using << to add child items to a parent collection, those items will not be counted in the parent's counter_cache if they already exist.
This only seems to happen if :order is specified on the has_many association. I assume it happens with other options, but I've only tested with :order.
Note that these items already exist within the database. Adding items via << for new entries seems to work fine.
BEFORE - NOT WORKING
class Expense < ActiveRecord::Base
belongs_to :invoice_line_item, :counter_cache => true
# more code...
end
class InvoiceLineItem < ActiveRecord::Base
has_many :expenses, :order => "created_on ASC"
# more code...
end
>> ili.expenses
=> []
>> ili.expenses << exp
=> [#<Expense id: 1, account_id: 3, person_id: 0, assigned_id: "000001", project_id: nil, invoice_line_item_id: 129484, category: "food", amount_in_cents: 20000, amount_currency: "USD", description: nil, created_on: "2009-10-07 18:06:00", is_billable: false>]
>> ili.expenses.count
=> 1
>> ili.expenses.size
=> 1
>> ili.reload
=> #<InvoiceLineItem id: 129484, account_id: 3, invoice_id: 58541, title: "line item", quantity: 0.0, price_per_in_cents: 0, price_per_currency: "", flat_fee_in_cents: 0, flat_fee_currency: "", final_cost_in_cents: 0, final_cost_currency: "USD", basecamp_id: nil, rank: nil, invoice_schedule_id: 0, line_item_id: nil, description: nil, is_taxable: true, person_id: nil, time_entries_count: 0, expenses_count: 0>
>> ili.expenses.size
=> 0
>> ili.expenses_count
=> 0
>> ili.expenses.count
=> 1
>>
AFTER - WORKING
class Expense < ActiveRecord::Base
belongs_to :invoice_line_item, :counter_cache => true
# more code...
end
class InvoiceLineItem < ActiveRecord::Base
has_many :expenses # REMOVED THE ORDER CLAUSE
# more code...
end
>> ili.expenses
=> []
>> ili.expenses << exp
=> [#<Expense id: 2, account_id: 3, person_id: 0, assigned_id: "000002", project_id: nil, invoice_line_item_id: 129485, category: "tools", amount_in_cents: 1000, amount_currency: "USD", description: nil, created_on: "2009-10-07 18:09:02", is_billable: false>]
>> ili.expenses.size
=> 1
>> ili.reload.expenses_count
=> 1
>> ili.expenses.size
=> 1
>>
Comments and changes to this ticket
-
Mark Turner October 8th, 2009 @ 08:31 AM
Cant Duplicate In Rails 2.3.4
app/models/invoice_line_item.rb
class InvoiceLineItem < ActiveRecord::Base has_many :expenses, :order => "created_at ASC" end
app/models/expense.rb
class Expense < ActiveRecord::Base belongs_to :invoice_line_item, :counter_cache => true end
Console Session:
Loading development environment (Rails 2.3.4) >> ili = InvoiceLineItem.new +----------------+------------+------------+ | expenses_count | created_at | updated_at | +----------------+------------+------------+ | | | | +----------------+------------+------------+ 1 row in set >> ili.save InvoiceLineItem Create (0.8ms) INSERT INTO "invoice_line_items" ("created_at", "expenses_count", "updated_at") VALUES('2009-10-08 07:26:05', NULL, '2009-10-08 07:26:05') => true >> ili +----+----------------+-------------------------+-------------------------+ | id | expenses_count | created_at | updated_at | +----+----------------+-------------------------+-------------------------+ | 7 | | 2009-10-08 07:26:05 UTC | 2009-10-08 07:26:05 UTC | +----+----------------+-------------------------+-------------------------+ 1 row in set >> ili.expenses << Expense.new Expense Create (0.3ms) INSERT INTO "expenses" ("created_at", "updated_at", "invoice_line_item_id") VALUES('2009-10-08 07:26:46', '2009-10-08 07:26:46', 7) InvoiceLineItem Load (0.2ms) SELECT * FROM "invoice_line_items" WHERE ("invoice_line_items"."id" = 7) InvoiceLineItem Update (0.1ms) UPDATE "invoice_line_items" SET "expenses_count" = COALESCE("expenses_count", 0) + 1 WHERE ("id" = 7) Expense Load (0.4ms) SELECT * FROM "expenses" WHERE ("expenses".invoice_line_item_id = 7) ORDER BY created_at ASC +----+----------------------+-------------------------+-------------------------+ | id | invoice_line_item_id | created_at | updated_at | +----+----------------------+-------------------------+-------------------------+ | 5 | 7 | 2009-10-08 07:26:46 UTC | 2009-10-08 07:26:46 UTC | +----+----------------------+-------------------------+-------------------------+ 1 row in set >> ili.expenses +----+----------------------+-------------------------+-------------------------+ | id | invoice_line_item_id | created_at | updated_at | +----+----------------------+-------------------------+-------------------------+ | 5 | 7 | 2009-10-08 07:26:46 UTC | 2009-10-08 07:26:46 UTC | +----+----------------------+-------------------------+-------------------------+ 1 row in set >> ili.expenses.size => 1 >> ili.expenses.count SQL (0.3ms) SELECT count(*) AS count_all FROM "expenses" WHERE ("expenses".invoice_line_item_id = 7) => 1 >> ili.expenses_count => nil >> ili.save => true >> ili.reload InvoiceLineItem Load (0.3ms) SELECT * FROM "invoice_line_items" WHERE ("invoice_line_items"."id" = 7) +----+----------------+-------------------------+-------------------------+ | id | expenses_count | created_at | updated_at | +----+----------------+-------------------------+-------------------------+ | 7 | 1 | 2009-10-08 07:26:05 UTC | 2009-10-08 07:26:05 UTC | +----+----------------+-------------------------+-------------------------+ 1 row in set >> ili.expenses.size => 1 >> ili.expenses_count => 1 >> ili.expenses.count SQL (0.3ms) SELECT count(*) AS count_all FROM "expenses" WHERE ("expenses".invoice_line_item_id = 7) => 1 >>
-
subimage October 8th, 2009 @ 08:41 AM
@Mark - read the original bug report. You missed the intent. It works when you use...
ili.expenses << Expense.new
What doesn't work is when you use...
expense = Expense.create ili.expenses << expense
However if you remove the :order option then re-run the above code it does work for the already existing expense.
-
Rohit Arondekar October 6th, 2010 @ 06:38 AM
- State changed from new to stale
- Importance changed from to
Marking ticket as stale. If this is still an issue please leave a comment with suggested changes, creating a patch with tests, rebasing an existing patch or just confirming the issue on a latest release or master/branches.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>