typeoneerror
typeoneerror

Reputation: 56998

Multiple activesupport concerns in mongoid model

I'm not sure I understand how concerns work. I am trying to wrap up some common code into two modules that extend ActiveSupport::Concern, but when I include both, I get a error:

`included': Cannot define multiple 'included' blocks for a Concern (ActiveSupport::Concern::MultipleIncludedBlocks)

module AppCore
  class Student
    include Mongoid::Document
    include Mongoid::Timestamps
    include AppCore::Extensions::Models::TenantScoped
    include AppCore::Extensions::Models::UserScoped
  end
end

module AppCore::Extensions::Models
  module TenantScoped
    extend ActiveSupport::Concern
    included do
      field :tenant_id, type: Integer
      belongs_to :tenant, class_name: 'AppCore::Tenant'
      association_name = self.to_s.downcase.pluralize
      AppCore::Tenant.has_many association_name.to_sym, class_name: self.to_s
    end
  end
end

module AppCore::Extensions::Models
  module UserScoped
    extend ActiveSupport::Concern
    included do
      field :user_id, type: Integer
      belongs_to :user, class_name: 'AppCore::User'
    end
  end
end

Can I only include one Concern at a time? Should I move the two Scoped modules to tenant_scoped and user_scoped to ClassMethods and just make one model extension concern?

Upvotes: 0

Views: 1037

Answers (2)

muichkine
muichkine

Reputation: 2940

Your problem is that you most likely not follow the Rails auto loading conventions regarding folder/file naming that follows the module / class name structure.

See Cannot define multiple 'included' blocks for a Concern (ActiveSupport::Concern::MultipleIncludedBlocks) with cache_classes = true for more info.

Upvotes: 1

jvans
jvans

Reputation: 2915

I'm not exactly sure what the problem with ActiveSupport::Concern but I'm not a huge fan of its abstraction. I would just use standard ruby to do what you're trying to accomplish and you won't have a problem. Change both of your modules to look like the following

module AppCore::Extensions::Models
  module UserScoped
    def self.included(klass)
      klass.class_eval do 
        field :user_id, type: Integer
        belongs_to :user, class_name: 'AppCore::User'
      end
    end
  end
end

Upvotes: 1

Related Questions