Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails namespacing concerns based on model name

I am looking to separate concerns for some subset of function specific to a model. I have referenced here and followed this pattern

module ModelName::ConcernName
  extend ActiveSupport::Concern

  included do
    # class macros
  end

  # instance methods
  def some_instance_method

  end

  module ClassMethods
    # class methods here, self included
  end
end

However, when I try to start the server it would result in the following error

Circular dependency detected while autoloading constant ModelName::ConcernName

I am wondering what is the best way to do concerns for some subset functions of a model.

Edit

Providing the model code: path: app/models/rent.rb

Now I have a lot of checking logic in my model

class Rent < ActiveRecord::Base
    def pricing_ready?
        # check if pricing is ready
    end

    def photos_ready?
        # check if photo is ready
    end

    def availability_ready?
        # check if availability setting is ready
    end

    def features_ready?
        # check if features are set
    end
end

I want to separate it in concern

class Rent < ActiveRecord::Base
    include Rent::Readiness
end

And organise the concern by namespace path: app/models/concerns/rent/readiness.rb

module Rent::Readiness
  extend ActiveSupport::Concern

  included do
    # class macros
  end

  # instance methods
  def pricing_ready?
    # check if pricing is ready
  end

  ...

  module ClassMethods
    # class methods here, self included
  end
end

Now I got it working if I just do class RentReadiness with the path in app/models/concerns/rent_readiness.rb

like image 551
Chris Yeung Avatar asked Dec 14 '22 06:12

Chris Yeung


2 Answers

You can scope it to Rents and place to concerns/rents/readiness.rb:

module Rents
  module Readiness
    extend ActiveSupport::Concern

    included do
      # class macros
    end
  end
end

And in model:

class Rent < ActiveRecord::Base
  include Rents::Readiness
end
like image 153
Artem P Avatar answered Dec 28 '22 05:12

Artem P


Rails uses activesupport to load classes and modules as they are defined by inferring the file path based on the class or module name, this is done as the Ruby parser loads your files and come across a new constant that has not been loaded yet. In your case, the Rent model is parsed up to the Rent::Readlines reference, at which point activesupport goes off to look for the rent/readlines.rb code file that matches the name. This file is then then parsed by ruby, but on the first line, The still unloaded Rent class is referenced, which triggers activesupport to go off and look for the code file that matches the name.

like image 27
maniacalrobot Avatar answered Dec 28 '22 05:12

maniacalrobot