I have a site that's working well but for one bug that I just found. I
have a generic "update record" method that sets various values. After
it's done setting them, it saves the record. A before_save on the
record is supposed to generically detect any interesting changes that
occurred.
My technique works as desired when the properties being changed are on
the record itself. When the property is virtual, representing
aggregates of other records, it's falling down.
At the end is a standalone pared down example of what I'm
experiencing. The problem is seen on line 40, but rooted on line 29.
In a nutshell, it looks like myRecord.manyItems is returning an array
of cached items, even after I .update() one of the records in that
array.
In case you have trouble running the example, here's my output on ruby
1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32] with Sequel 2.10.0:
Initially :: 1 + 2 = 3
Set own_value to 4:
...own_value changed from 1 to 4
...value changed from 3 to 6
AfterSave :: 4 + 2 = 6
Refetched :: 4 + 2 = 6
Set votes to 8:
...vote_total before change: 2
...vote_total SHOULD become 8
...vote_total ACTUALLY became 2
...value changed from 12 to 6
AfterSave :: 4 + 2 = 6
Refetched :: 4 + 8 = 12
Finally, here's the test code. Thanks for any light you can shed on
how I can get the vote_total method to not use cached data.
require 'rubygems'
require 'sequel'
DB = Sequel.sqlite
DB << <<ENDSQL
CREATE TABLE ideas (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
own_value INTEGER NOT NULL
);
CREATE TABLE votes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
idea_id INTEGER NOT NULL,
count INTEGER NOT NULL
);
ENDSQL
class Vote < Sequel::Model; end
class Idea < Sequel::Model
has_many :votes
def value
own_value + vote_total
end
def vote_total
votes.inject(0){ |sum,vote| sum + vote.count }
end
def votes=( new_votes )
orig = vote_total
puts "...vote_total before change: #{orig}"
vote = Vote.filter( :idea_id=>self.pk ).first
puts "...vote_total SHOULD become #{orig-vote.count+new_votes}"
vote.update( :count=>new_votes )
puts "...vote_total ACTUALLY became #{vote_total}"
end
before_save do
old_idea = Idea[ pk ]
%w| own_value value |.each{ |s|
old_value, new_value = old_idea.send(s), self.send(s)
if old_value != new_value
puts "...#{s} changed from #{old_value} to #{new_value}"
end
}
end
end
Idea << { :name=>"Peace", :own_value=>1 }
$i = Idea.first
Vote << { :idea_id=>$i.pk, :count=>2 }
puts "Initially :: #{$i.own_value} + #{$i.vote_total} = #{$i.value}"
puts "\nSet own_value to 4:"
$i.update( :own_value => 4 )
puts "AfterSave :: #{$i.own_value} + #{$i.vote_total} = #{$i.value}"
$i = Idea.first
puts "Refetched :: #{$i.own_value} + #{$i.vote_total} = #{$i.value}"
puts "\nSet votes to 8:"
$i.update( :votes => 8 )
puts "AfterSave :: #{$i.own_value} + #{$i.vote_total} = #{$i.value}"
$i = Idea.first
puts "Refetched :: #{$i.own_value} + #{$i.vote_total} = #{$i.value}"
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"sequel-talk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/sequel-talk?hl=en
-~----------~----~----~----~------~----~------~--~---