【问题标题】:Dynamically Generating Scopes with Descendants of a Model动态生成具有模型后代的范围
【发布时间】:2018-04-21 22:38:22
【问题描述】:

我在为我的 STI 模型动态生成范围时遇到问题。这是模型结构:

app/models/unit.rb

class Unit < ApplicationRecord
  def self.types
    descendants.map(&:name)
  end

  # Dynamically generate scopes for STI-related models
  types.each do |type|
    scope type.tableize.to_sym, -> { where(type: type) }
  end
end

app/models/units/academy.rb

class Academy < Unit
end

app/models/units/faculty.rb

class Faculty < Unit
end

config/environment/development.rb

config.eager_load = false

# Enable auto-load only for these files
Rails.application.reloader.to_prepare do
  Dir[
    Rails.root.join('app', 'models', '**', '*.rb')
  ].each { |file| require_dependency file }
end

当我在开发模式下进入 Rails 控制台时,我可以像这样轻松检查单元类型:

Unit.types
["Academy", "Faculty"]

但是我无法达到预期的范围(例如 Unit.faculties、Unit.academies),因为 Rails 无法为我生成范围,因为它将“类型”作为空数组。我的意思是 Unit 模型的这一部分:

types.each do |type|
  scope type.tableize.to_sym, -> { where(type: type) }
end

即使在开发模式下,我也可以从控制台检查类型,但在动态生成范围时,类型返回一个空数组。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-5 metaprogramming


    【解决方案1】:

    问题是后代类没有被实例化。以下解决方法将帮助您实现所需的目标:

    def self.types
      ActiveRecord::Base.connection.tables.map {|t| t.classify.constantize rescue nil}.compact
      descendants.map(&:name)
    end
    

    但就个人而言,我认为您根本不需要这些范围,因为在后代类上调用 all 将提供查询:

    Faculty.allUnit.where(type: "Faculty") 相同

    Academy.allUnit.where(type: "Academy") 相同

    【讨论】:

      猜你喜欢
      • 2012-12-13
      • 2015-01-20
      • 1970-01-01
      • 2019-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多