Rails命名空间基于模型名称的关注点

时间:2016-05-29 07:27:14

标签: ruby-on-rails separation-of-concerns

我希望将某些特定功能子集的关注点分开。 我引用了guide并遵循了这种模式

M=$(PWD) modules

但是,当我尝试启动服务器时,会导致以下错误

  

自动加载常量ModelName :: ConcernName

时检测到循环依赖关系

我想知道对模型的某些子集函数关注的最佳方法是什么。

修改

提供型号代码: 路径:app / models / rent.rb

现在我的模型中有很多检查逻辑

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

我想将其分开关注

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

并按命名空间组织关注 路径:app / models / concerns / rent / readiness.rb

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

现在,如果我只使用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

中的路径进行课程RentReadiness,我就能正常工作

3 个答案:

答案 0 :(得分:3)

Rails使用activesupport加载类和模块,因为它们是通过基于类或模块名称推断文件路径来定义的,这是在Ruby解析器加载文件并遇到尚未加载的新常量时完成的。 。在您的情况下,Rent模型被解析为Rent::Readlines引用,此时activesupport将查找与该名称匹配的rent/readlines.rb代码文件。然后由ruby解析此文件,但在第一行,引用仍然未加载的Rent类,这会触发activesupport关闭并查找与名称匹配的代码文件。

答案 1 :(得分:2)

您可以将其范围限定为Rents并放置到concerns/rents/readiness.rb

module Rents
  module Readiness
    extend ActiveSupport::Concern

    included do
      # class macros
    end
  end
end

在模特中:

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

答案 2 :(得分:2)

您可以通过将具有特定于模型的关注点的文件夹从concerns移动到models来使其生效。所以,你会有:

models/
    rent.rb
    rent/
        readiness.rb   

我喜欢这种使用模型作为其关注点的命名空间的约定,因为它允许您从代码中删除一些冗余:

  • 由于您在模型类中定义了关注点,因此在模型中您可以编写include Readiness而不是include Rent::Readiness
  • 定义问题时,您可以使用module Rent::Readiness代替

    class Rent < ApplicationRecord
         module Readiness
    ...
    

    这是解决您在问题中提到的循环依赖问题的另一种方法。