Home Ask Login Register

Developers Planet

Your answer is one click away!

James B. Byrne February 2016

Q&A. Trailbalzer Testing - Implications of contract method

The following Q&A is based on the examples given in the Trailblazer book pp. ~50-60 as adapted for my specific requirements. You can simply think of ARInvoice and ar_invoice as Thing and thing to get the general drift if following in the book.

My operation.rb file for this was:

class ARInvoice < GLTransaction   class Create <

    include( Model )
    model( ARInvoice, :create )

    contract() do
      property( :invoice_number )
      property( :currency_code )
      property( :forex_rate )
      property( :gl_account_id )

      validates( :invoice_number, :presence => true )
      validates( :currency_code, :presence => true )

    def process( params )
      @model = ARInvoice.new  # have to use instance variable here
      validate( params[ :ar_invoice ], @model ) do |f|

I adapted this test from the trailblazer book:

it("INSERTs a valid invoice") do
  test_time = Time.now
  ar_invoice = ARInvoice::Create.(
    :ar_invoice => {
      :invoice_number => 101,
      :gl_account_id => 1,
      :effective_from => test_time.to_s


And I got this error:

ar_invoice crud Create#test_0001_INSERTs a valid invoice: \
ActiveRecord::StatementInvalid: SQLite3::ConstraintException: \
gl_transactions.effective_from may not be NULL: \
INSERT INTO "gl_transactions" . . .

But I also see this:

# Running:
2016-02-08 11:24:35 -0500

So, test_time value is set. Why is it not getting into the effective_from


James B. Byrne February 2016

The problem was that I did not grasp the significance of the contract do/end block as used in Trailblazer (TBR). The way I initially read the book was that the contract is concerned with the form. My experience with RoR led me to map the word form with the word view. My mistake. But one that might trip someone else as well.

The correct contract block contains the missing attribute: effective_from

contract() do
  property( :invoice_number )
  property( :currency_code )
  property( :forex_rate )
  property( :gl_account_id )

  property( :effective_from )

  validates( :invoice_number, :presence => true )
  validates( :currency_code, :presence => true )

For now, it helps me if I map the word form to params[ :model ]. Because the attributes that are looked for in the params[ :model ] hash when the process method is called are limited to those attributes explicitly listed in the contract do/end block; Which is why Strong Parameters are unneeded when using TBR.

Note that the original test still fails because the currency_code validation is not met. But that was intentional at the time this test was written.

Post Status

Asked in February 2016
Viewed 2,092 times
Voted 11
Answered 1 times


Leave an answer

Quote of the day: live life