PlankTon
PlankTon

Reputation: 12605

Rails: Appending methods to activerecord (the right way?)

I'm messing around with creating a rails gem and I'm having trouble adding methods to ActiveRecord. Let's say I want to do the following:

class DemoModel < ActiveRecord::Base
  custom_method :first_argument, :second_argument
end

In order to make this work, I throw in the following:

module DemoMethod

  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods       
    def custom_method(*fields)
      @my_fields = fields
    end
  end

end

ActiveRecord::Base.send(:include, DemoMethod)

So far, so good.

The problem is, I then want to access that my_fields variable from the instance of the model. For example, I might open up form_for with something like:

module ActionView::Helpers::FormHelper
  def fields_for(record_name, record_object, options = {}, &block)
    the_fields = record_object.<I WANNA ACCESS @my_fields HERE!!!>.html_safe
    # ...
  end
end

The difficulty is, 'custom_method' only seems to work if I set the helper as a class method, but that means .self is now the Model (DemoModel) instead of the DemoModel object on which I want to work. I could pass in the object manually with "custom_method self, :first_argument, :second_argument", but it seems a little clumsy to ask the users of my wonderful "custom_method" gem to have to prepend 'self' to their list of arguments.

So, the question is, how would a wiser Rails person set values for a specific object through custom_method, and then retrieve them somewhere else, such as fields_for?

As always, any suggestions appreciated.

Upvotes: 0

Views: 397

Answers (1)

Shaun
Shaun

Reputation: 549

Using the self.included and ClassMethods adds the methods as class methods.

Defining methods normally within the module, and then including them, is the way to create ordinary instance methods. Like so:

module DemoMethod

   def custom_method(*fields)
    @my_fields = fields
  end
end

ActiveRecord::Base.send(:include, DemoMethod)

Upvotes: 2

Related Questions