Francis.TM
Francis.TM

Reputation: 1811

Define instance methods in Concern dynamically on Rails

I just want to convert user input params into a Time object, so I trying to define a concern for that.

class Foo < ActiveRecord::Base
  include DateAttribute
  attr_date :date_column_1, :date_column_2
end

But when I write that concern, I got a problem that how to define a instance methods in module's class_methods block.

module DateAttribute
  extend ActiveSupport::Concern

  included do
    class_attribute :_attr_date, instance_accessor: false

    self._attr_date = []
  end

  class_methods do
    def attr_date(*attributes)
      self._attr_date = Set.new(attributes.map(&:to_s))

      # how to dynamic define setter methods by loop attributes here
    end

    def date_attributes
      self._attr_date
    end
  end
end

Thanks.

Upvotes: 1

Views: 3687

Answers (1)

Qaisar Nadeem
Qaisar Nadeem

Reputation: 2424

You can use class_eval to dynamically create methods.

Here is a simple implementation

module DateAttribute
  extend ActiveSupport::Concern

  included do
    class_attribute :_attr_date, instance_accessor: false

    self._attr_date = []
  end

  class_methods do
    def attr_date(*attributes)
      self._attr_date = Set.new(attributes.map(&:to_s))
       attributes.each do |attrib|
        class_eval <<-RUBY
        def #{attrib}(*arguments)
         arguments
        end

        def #{attrib}=(value)
          value
        end
      RUBY
      end
    end

    def date_attributes
      self._attr_date
    end
  end
end

Here is a great article to deal with such stuff and you can find dynamic method creation guide from Dynamic Method Creation

Upvotes: 4

Related Questions