Replacing ActiveRecord with trailblazer

337 Views Asked by At

Environment:

CentOS-6.7 / OSX-10.9.5
Ruby 2.2.3p173 (probably time for an update)
Rails 4.2.5.1
Trailblazer 1.1.0

I am working through the exercises in the trailblazer book and attempting to map elements of an existing project to the examples in the book. In the project at hand we use AR inheritance to create model aliases for a single underling table. An example is given below:

class ARAccount< GLAccount
  after_initialize( :set_sub_ledger,  { :if => :new_record? } )
  has_one(  :active_client,
            -> { where IsActiveRow },
            :class_name => 'ARClient',
            :dependent => :restrict_with_error,
            :foreign_key => :gl_account_id
         )

  def gl_sub_ledger=( code )  # No change to sub_ledger value allowed
     gl_sub_ledger ||= AR_SUB_LEDGER   # Return 'AR' if not saved
  end

  private

  def set_sub_ledger          # set fixed value for AR sub_ledger
    write_attribute( :gl_sub_ledger, AR_SUB_LEDGER ) if new_record?
  end

  self.inheritance_column = :gl_ledger
  def sti_name
    "ASST"
  end
end

The way this works is borrowed from single table inheritance in that a column value is 'fixed' for each variant model definition but the underlying table and row is identical for all variants.

I am somewhat confused as how how this would be handled inside the operation.rb file within the ar_invoice concerns. This AR set up evolved after some struggles with AR to handle inheritance and so I am very much interested a simpler way demonstrated using Trailblazer.

1

There are 1 best solutions below

0
On

An answer one year too late.

Here's the ARAccount::Create operation.

class ARAccount::Create < Trailblazer::Operation
  step Model( ARAccount, :new ) # this creates a new model for you.
  step :set_sub_ledger
  step # ... whatever you need after that.

  def set_sub_ledger(options, model:, **) # set fixed value for AR sub_ledger
    model.write_attribute( :gl_sub_ledger, AR_SUB_LEDGER )
  end
end

Since you had this if new_record? check, you don't need the set_sub_ledger step in Update.

class ARAccount::Update < Trailblazer::Operation
  step Model( ARAccount, :find ) # this finds an existing model for you.
  step # ... whatever you need after that.
end

The model is pretty slim now.

class ARAccount< GLAccount
  has_one(  :active_client,
        -> { where IsActiveRow },
        :class_name => 'ARClient',
        :dependent => :restrict_with_error,
        :foreign_key => :gl_account_id
     )

  self.inheritance_column = :gl_ledger
  def sti_name
    "ASST"
  end
end

You usually leave scopes and finders in the model until you introduce Query objects.