代码之家  ›  专栏  ›  技术社区  ›  Sig

基于其他模型创建动态作用域

  •  0
  • Sig  · 技术社区  · 6 年前

    在Rails(5.0)应用程序中,我有以下内容

    class Batch < ApplicationRecord
      belongs_to :zone, optional: false
    end
    
    class Zone < ApplicationRecord
      scope :lines, -> { where(kind: 'line') }
    end
    

    Batch 每个人的范围 Zone 这是一条线。类似下面的代码可以工作。

      Zone.lines.map(&:name).each do |name|
        scope "manufactured_on_#{name}".to_sym, -> { joins(:zone).where("zones.name = '#{name}'") }
      end
    

    区域 同类的 line ,未创建作用域。

    有办法解决这个问题吗?

    3 回复  |  直到 6 年前
        1
  •  3
  •   Samy Kacimi    6 年前

    可以将区域名称作为作用域参数传递

    scope :manufactured_on, -> (name) { joins(:zone).where(zones: { name: name } ) }
    
        2
  •  0
  •   Michał Szajbe    6 年前

    您可以查看文档并搜索 method_missing .

    相反,请按以下方式定义范围:

    class Batch < ApplicationRecord
      scope :manufactured_on, ->(line) { joins(:zone).where("zones.name = '#{name}'") }
    end
    

    然后简单地使用

    Batch.manufactured_on(zone.name)
    
        3
  •  0
  •   Gokul    6 年前

    method_missing 如下所示:

    class Batch < ApplicationRecord
      belongs_to :zone, optional: false
    
      def self.method_missing(name, *args)
        method_name = name.to_s
    
        if method_name.start_with?('manufactured_on_')
          zone_name = method_name.split('manufactured_on_')[1]
          joins(:zone).where(zones: { name: zone_name } )
        else
          super
        end
      end
    
      def self.respond_to_missing?(name, include_private = false)
        name.to_s.start_with?('manufactured_on_') || super
      end
    end
    

    Batch.manufactured_on_zone_a