ruby on rails - RoR 4.x approach for managing transactions best practices -


first of - sorry perhaps stupid questions i'm beginner in ror world , need basic clarity on how database transactions work within models / controllers. come java world things done in way , when working ror naturally compare java web frameworks hence confusion if looks radically different :-)

in 1 of controller actions, need modify , save multiple of models, let's say: order, invoice, payment.

from understand, standard "save" method on each model executes in it's own transaction therefore if write:

payment.save order.save invoice.save 

this create 3 independent db transactions , each model saved in it's own transactions - not want since i'd make sure either or none of these models saved.

i found article: http://markdaggett.com/blog/2011/12/01/transactions-in-rails/ demonstrates how wrap multiple "saves" single transaction. it's old hope still valid (correct me if i'm wrong).

one thing don't need manage these transactions explicitly in each controller action need it. prefer happen "behind scenes" "open session in view" pattern known java world db transaction started in filter before db query executed , transaction committed in filter after controller actions have finished.

i thinking using similar approach in ror application, found blog post demonstrating how it: http://blog.endpoint.com/2011/10/rails-controllers-and-transactions.html i'm not sure whether "best practice" since other article (http://markdaggett.com/blog/2011/12/01/transactions-in-rails/) says "use of transactions in controller common anti-pattern avoid" (not sure why though).

would able direct me "right" approach?

thank you,

michal

transactions model-layer concern. don't think belong in controller, although work. it's not hard rule.

one thing consider code need run outside context of controller? example in background job? or rake task? in case consolidating logic model layer make easier reuse.

to accomplish in model layer, "rails way" make use of callbacks. *_save/create/update callbacks automatically executed within current database transaction, means desired transaction behavior "for free" without explicitly writing transaction code.

if models have clear parent-child relationship, can register callbacks on "top level" model, e.g.:

class order < activerecord::base   has_one :invoice   has_one :payment    after_create :save_child_records    private    def save_child_records     invoice.save!     payment.save!   end end  order.save # triggers invoice.save! , payment.save!  # in 1 transaction 

alternatively, create brand new model not backed database table, serves orchestrate multiple models. called "service object" or "operation object".

for recommend active_type gem, lets use standard activerecord callbacks, therefore gives same desirable transaction behavior:

class processpayment < activetype::object   attr_accessor :order, :invoice, :payment    # can declare activerecord validations here   # or register other before_save callbacks business logic    before_save :save_records    private    def save_records     order.save!     invoice.save!     payment.save!   end end  process_payment.save # order, invoice, payment saved in single transaction 

Comments

Popular posts from this blog

How has firefox/gecko HTML+CSS rendering changed in version 38? -

javascript - Complex json ng-repeat -

jquery - Cloning of rows and columns from the old table into the new with colSpan and rowSpan -