I have a "transaction" (extends ActiveRecord::Base). I have two different types of transactions, a "Purchase" or a "Donation". There's enough overlap between the two that there's no need to create two separate database tables, so I just have one table for the transactions with an "item_type" column.
However, there are different methods and validations for a Purchase and Donation, so it makes sense to break them up into two different controllers and models. Instead of creating ActiveBase models (minus the tables), I'm trying to use Modules for each of these.
Here is what the Purchase module looks like.
module Purchase
def self.included(base)
base.validates :amount,
:presence => true
end
def testing
"testing"
end
end
Here is how one is created: (this code is in the create action of the Purchases controller)
@purchase = Transaction.new(params[:purchase]).extend(Purchase)
I am able to call @purchase.testing and it returns "testing". However, that validation is not being run.
If I include the module in the traditional fashion on the Transaction model, with "include Purchase", then they work.
Any ideas how I can make this workflow happen? I followed this a bit: http://paulsturgess.co.uk/articles/84-how-to-include-class-and-validation-methods-using-a-module-in-ruby-on-rails
If you only want to work with a single table and multiple columns, I think the preferred approach is single table inheritance. You can read about it here if you search for single table inheritance. With regards to your question, though, about how to include the module, I think you'll want to include the module in the metaclass for @purchase
so it isn't included in all subsequent Transactions. Kind of like this (can definitely be shortened):
@purchase = Transaction.new(params[:purchase])
class << @purchase
include Purchase
end
Then, your validation should work.
Your included
hook will not be run when you do .extend(Purchase)
. You need an extended
hook for that. Inside the extended
hook, you can call the Rails validation helpers on the eigenclass of the new Transaction
object (similar to what @Adam demonstrated).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With