检查Rails控制器中是否有模型

3
在下拉列表中,我动态获取了所有控制器类及其操作,并在另一个下拉列表中使用它们进行某些操作。有些控制器没有任何模型,例如'DashboardsController'没有Dashboard模型,只是用于显示仪表板。
因此,基本上我需要过滤掉没有模型的控制器。我需要一个方法,通过传递控制器类,返回true/false
def has_model?(controller_klass)
 # TODO
end 
2个回答

2

如果您将控制器的名称作为字符串传递,可以尝试以下解决方案。该解决方案假定您的模型在Rails 5之前使用了 ActiveRecord 来定义模型; 在这种情况下,只需将 ActiveRecord::Base 替换为 ApplicationRecord。另外,如果您有一些纯粹的 Ruby 对象 (POROs) 的模型,则此解决方案将无法为它们工作。

def has_model?(controller_klass)
  begin
    class_string = controller_klass.to_s.gsub('Controller', '').singularize
    class_instance = class_string.constantize.new
    return class_instance.class.ancestors.include? ActiveRecord::Base 
  rescue NameError => e
    return false
  end
end 

1
删除了我的回答,这个更好。 - SteveTurczyn
顺便说一下,我正在使用Rails 4。 - Arif
是的,调用constantize的那行代码没有将新常量赋值给class_instance变量。已修复。 - C dot StrifeVII
最后,ApplicationRecord是ActiveRecord::Base的一个子类。你可能不需要为Rails 5更改任何内容。但并不推荐在常见情况下依靠异常。 - Eric Duminil
它将为提供的示例引发异常:DashboardsController。 - Eric Duminil
显示剩余6条评论

0

这种方法不依赖于异常,并且可以使用类或字符串作为输入。它应该适用于任何Rails版本:

def has_model?(controller_klass)
  all_models = ActiveRecord::Base.descendants.map(&:to_s)
  model_klass_string = controller_klass.to_s.sub(/Controller$/,'').singularize
  all_models.include?(model_klass_string)
end

注意:你需要设置


config.eager_load = true

config/environments/development.rb

如果您有非 ActiveRecord 模型,您可以忽略前面的注释并使用:

all_models = Dir[File.join(Rails.root,"app/models", "**","*.rb")].map{|f| File.basename(f,'.rb').camelize}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接