Hello, All: I am grappling with an interesting problem that I can't believe I'm the first to tackle. Hoping someone has covered this ground before, or is experienced enough to give good suggestions, and can suggest a reasonable path forward.
The issue is related to transactions and ActiveRecord::Timestamp. Specifically, if we insert or update multiple rows in a single transaction, each row gets a slightly different updated_at/created_at timestamp. The reason is because instead of using the SQL function NOW() to set the created/updated times, the ruby code generates the timestamps at the time the SQL for the insert/update is created. The problem is that we need the timestamps on rows added/updated in the same transaction to match (for auditing and perceived atomicity reasons). As I allude to above, if ActiveRecord used the sql function NOW() to set the created_on/updated_on times, they would all be the time that the database server began the transaction. (See now() explanation at e.g. http://www.postgresql.org/docs/8.2/static/functions-datetime.html ) But I understand that setting updated_on/created_on times to NOW() is tricky through ActiveRecord. Here are some ideas we've thrown around to fix this, and our thoughts on each: Idea 1: Fetch NOW() from the database at the beginning of the transaction, and use that verbatim for all updated_on/created_on times that need to get set Thoughts: inconsistent with the Rails model, which always uses the time on the ruby side, not the database. Also adds a roundtrip to the database. Idea 2: Mixin new modules to ActiveRecord::Base to override the transaction() call, record the time, and then call super(). Also override the Timestamp current_time_from_proper_timezone method to return the time that our transaction() call squirrelled away. Theres a little more to this (clearing the timestamp when the transaction is committed or rolled back), but you get the idea Thoughts: Modifies ActiveRecord::Base to be more different than might be obvious. We think we prefer the next idea (3). Idea 3: Subclass ActiveRecord::Base (to say ActiveRecordLocal) and mix in the modules mentioned above into this class. Thoughts: This makes is clearer that when you're using ActiveRecordLocal, you're not getting the stock ActiveRecord::Base behavior. Otherwise this solution is identical to Idea 2. Idea 4: when then transaction starts, use Timecop::freeze to freeze the time that ruby sees. Thoughts: We can't freeze the time for all code in the app while a transaction is pending. Plus Timecop is for testing, not production use-- but most importantly see previous point. We've seen other ideas which we rejected and won't bring up here. So, after all this motivation -- the questions; Q1: Has anyone tacked this issue before? How did you solve it? Is there an easy way to accomplish our goal? Q2: What strategy do you think we should take to fix this issue? (Either one explained above, or another strategy)? At this point we're moving forward with* Idea 3*, but I'd love to hear some experienced people's input on this topic Best, "RubyRailHead" -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscr...@googlegroups.com. To post to this group, send email to rubyonrails-talk@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/87f64321-6c06-416b-a9b2-3584e2cb8224%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.