views:

62

answers:

2

I have been building a Rails application that performs accounting functionality. As part of this, I have a model with the class name Transaction. So far so good, I have been building this functionality for a month or so, and everything is working as expected.

Until now...

I have just discovered some older reporting functionality that was developed months ago using the Ruport library has stopped working. It appears that Ruport, when generating PDFs, requires a library that also has a class/module named Transaction.

TypeError in Admin/team reportsController#generate
Transaction is not a module

...

This error occurred while loading the following files:
  pdf/writer
  transaction/simple

So, I'm looking for a quick fix here. One that hopefully doesn't involve renaming my Transaction model and refactoring the last few weeks worth of code.

Looking forward to some clever suggestions :)

+1  A: 

Your problem may come from the fact that Transaction is also a reserved word in Rails…

Yannis
Is it? Damn! But thanks for informing me...
aaronrussell
Rails is just a Ruby library, it cannot add any keywords to the Ruby language.
Jörg W Mittag
+3  A: 

I believe the issue is down to Ruport requiring the PDF::Writer gem, which in turn requires the Transaction::Simple gem which defines the module Transaction.

There is certainly a #transaction method in ActiveRecord, but I do not think there is a Transaction module or class within Rails. I'll be happy to be corrected on that one.

Namespacing is usually the best practice for avoiding naming conflicts like this. E.g.

module Account
  class Transaction < ActiveRecord::Base
    ....
  end
end 

However, namespacing ActiveRecord models may throw up other issues.

As time consuming as it may be, renaming your Transaction model may be the best bet.

You can still keep your existing transactions database table if you wanted, so your migrations don't need to change, by putting set_table_name "transactions" inside your model.

Your associations with other models can also still be named "transaction(s)" by specifying the class_name in your association call. E.g.

class User < ActiveRecord::Base

  has_many :transactions, :class_name => "AccountTransaction"

end

Those two suggestions may or may not save you some time.

Sidane
Thanks. I have changed your answer to the accepted answer as it more accurately describes the specific problem I have - although Yannis, answer is also correct! In the end I resorted to renaming my model, database table, and all associations using some old-skool find and replace ;)
aaronrussell