Transaction rollback on callback returning false on Rails Edge

Posted by kain Sun, 24 Aug 2008 15:28:00 GMT

Previously this would have committed the transaction but not carried out save or destroy operation.

The entire callback chain of a save, save!, or destroy call runs within a transaction. That includes after_*hooks. If everything goes fine a COMMIT is executed once the chain has been completed.

If a before_* callback cancels the action a ROLLBACK is issued. You can also trigger a ROLLBACK raising an exception in any of the callbacks, including after_* hooks.

Note, however, that in that case the client needs to be aware of it because an ordinary save will raise such exception instead of quietly returning false.

link to changeset

*evil* catch-all method for your STI pleasure

Posted by kain Thu, 03 Jul 2008 22:39:00 GMT

 Yes, you have a User model, an Admin one and even an Operator one.

Those are subclasses of Account, which means you are using single table inheritance, and you have the magic field "type" in your accounts table.

Then you realize you have to write some ACLs in your controllers, and you start to get overwhelmed with all those conditionals.

Would be sweet to call something like:

this_user.is_admin_or_operator?

Put this in your Account model

  # Would be neat to walk every subclass of Account, I tried but results
  # are unpredictable with config.cache_classes = false
  SUBCLASSES_KEYWORDS = %w(admin user)
  # Evil catch-all for methods like is_admin_or_user. Ehe.
  def method_missing(method_name, *arguments)
    return super unless method_name.to_s =~ /\Ais_.*(?:#{SUBCLASSES_KEYWORDS.join('|')})/
    method_name.to_s.scan(Regexp.union(*SUBCLASSES_KEYWORDS)).include?(self.class.to_s.downcase)
  end

Handle with care and remember that this will break docs (of course) and respond_to?, so at least write a respond_to? method with the same regex.