Rails:如何基于控制器类名获取模型类名?


Answers:


190

这样做:

class HouseBuyersController < ApplicationController

  def index
    @model_name = controller_name.classify
  end

end

当抽象控制器动作时,通常需要这样做:

class HouseBuyersController < ApplicationController

  def index
    # Equivalent of @house_buyers = HouseBuyer.find(:all)
    objects = controller_name.classify.constantize.find(:all)
    instance_variable_set("@#{controller_name}", objects)
  end

end

@model_name = controller_name.classify#返回“ HouseBuyers”,谢谢!
彼得·埃里希

1
ActiveSupport :: Inflector很棒
Jared Beck

根据您的需求(此问题未指定任何详细信息),您可以controller_name.sub('_', ' ').titleize获取“房屋购买者”。
user664833

将逻辑(用于获取模型类)移动到单独的实用程序方法中可能会很好。如果将结果存储在一个常量中,则更好,以加快访问速度。您可以new.controller_name.classify.constantize在类定义中使用。
开尔文

我认为值得注意的是,这甚至可以在应用程序控制器中工作,具体取决于哪个控制器继承自它。
weltschmerz

40

如果您的控制器和模型在同一个名称空间中,那么您想要的是

controller_path.classify

controller_path给您命名空间;controller_name不。

例如,如果您的控制器是

Admin::RolesController

然后:

controller_path.classify # "Admin::Role" # CORRECT
controller_name.classify # "Role"        # INCORRECT

6

这有点骇人听闻,但是如果您的模型是以您的控制器名称命名的,则:

class HouseBuyersController < ApplicationController
  def my_method
    @model_name = self.class.name.sub("Controller", "").singularize
  end
end

...会在您的@model_name实例变量中给您“ HouseBuyer”。

同样,这是一个巨大的假设,即“ HouseBuyersController”仅处理“ HouseBuyer”模型。


4

对于有效的名称空间:

def resource_class
 controller_path.classify.constantize
end

0

如果您使用的是默认的MVC,这似乎是不可能的,但是您的代码似乎并不遵循。您的控制器似乎是一个模型,但也许您只是那里有一个类型。无论如何,在Rails MVC中,控制器和模型从根本上是分开的,因此控制器无法知道它们与哪个模型关联。

例如,您可能有一个名为post的模型。这可以有一个控制器posts_controller,也可以有一个类似articles_controller的控制器。当您在控制器中定义实际代码时,Rails仅了解模型

def index
  @posts = Post.all
  @posts = Article.all
end  

在Rails标准控制器中,无法知道模型是什么。


0

接受的解决方案对我不起作用,因为我的控制器和模型已命名。相反,我想出了以下方法:

def controllers_model
  (self.class.name.split('::')[0..-2] << controller_name.classify).join('::')
end
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.