How to inherit class methods using ActiveSupport::Concern

2k views Asked by At

I have a small hierarchy of classes in my Ruby on Rails application. I have tried to add a concern with supports describing the classes with some information that I would like to be inherited by the child classes. The problem can be illustrated with this small sample:

module Translatable
  extend ActiveSupport::Concern

  included do
  end

  module ClassMethods
    def add_translatable_fields(field_and_types)
      @translatable_fields ||= {}
      @translatable_fields.merge! field_and_types
    end

    def translatable_fields
      @translatable_fields
    end
  end
end

class Item
  include Translatable

  add_translatable_fields({name: :string})
end

class ChildItem < Item
end

class AnotherItem < Item
  add_translatable_fields({description: :text})
end

puts "Item => #{Item.translatable_fields.inspect}"
puts "ChildItem => #{ChildItem.translatable_fields.inspect}"
puts "AnotherItem => #{AnotherItem.translatable_fields.inspect}"

I would have like this sample code to return

Item => {name: :string}
ChildItem => {name: :string}
AnotherItem => {name: :string, description: :text}

But unfortunately the ChildItem and AnotherItem does not add the class "properties" set on the parent class and it instead returns

Item => {name: :string}
ChildItem => nil
AnotherItem => {description: :text}

How can I make the class inheritence work the way I want it to?

1

There are 1 answers

1
evanbikes On

It looks like the child classes are inheriting correctly from the parent, but the issue is the class variables.

I'll bet you could do

class ChildItem < Item
  add_translatable_fields(Item.translatable_field)
end

But I just learned about these Rails helpers, and it seems more like what you're looking for.

http://api.rubyonrails.org/classes/Class.html#method-i-class_attribute

You could define the class_attribute in the included block and it should inherit to all the children the way you want it to.