我在为STI模型动态生成范围时遇到问题。这是模型结构:
应用程序/模型/ 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
应用程序/模型/单位/ academy.rb
class Academy < Unit
end
应用程序/模型/单位/ faculty.rb
class Faculty < Unit
end
配置/环境/ 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无法为我生成范围,因为它有&#39;类型&#39;作为一个空数组。我的意思是单元模型的这一部分:
types.each do |type|
scope type.tableize.to_sym, -> { where(type: type) }
end
即使在开发模式下,我也可以从控制台检查类型,但是当涉及到动态生成作用域时,类型会返回一个空数组。
答案 0 :(得分:2)
问题是后代类没有实例化。以下解决方法将帮助您实现您正在寻找的内容:
def self.types
ActiveRecord::Base.connection.tables.map {|t| t.classify.constantize rescue nil}.compact
descendants.map(&:name)
end
但就个人而言,我认为你根本不需要这些范围,因为在后代类上调用all
将提供查询:
Faculty.all
与Unit.where(type: "Faculty")
Academy.all
与Unit.where(type: "Academy")