Rails: How to get the model class name based on the controller class name?

前端 未结 6 2054
别那么骄傲
别那么骄傲 2020-12-22 20:49
class HouseBuyersController < ...
  def my_method
    # How could I get here the relevant model name, i.e. \"HouseBuyer\" ?
  end
end
相关标签:
6条回答
  • 2020-12-22 20:55

    For namespaces working:

    def resource_class
     controller_path.classify.constantize
    end
    
    0 讨论(0)
  • 2020-12-22 20:55

    The accepted solution did not work for me as my controller and model was namespaced. Instead, I came up with the following method:

    def controllers_model
      (self.class.name.split('::')[0..-2] << controller_name.classify).join('::')
    end
    
    0 讨论(0)
  • 2020-12-22 21:07

    It's a bit of a hack, but if your model is named after your controller name then:

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

    ... would give you "HouseBuyer" in your @model_name instance variable.

    Again, this makes a huge assumption that "HouseBuyersController" only deals with "HouseBuyer" models.

    0 讨论(0)
  • 2020-12-22 21:09

    This is not possible if you are using the default MVC, which your code doesn't seem to follow. Your controller seems to be a model but maybe you just got a type there. Anyway, controllers and models are fundamentally separated in Rails MVC so controllers cannot know which model they are associated with.

    For example you could have a model named post. This can have a controller posts_controller or could have a controller like articles_controller. Rails only knows about models when you def the actual code in the controller such as

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

    In rails standard controllers there is no way to know what the model is.

    0 讨论(0)
  • 2020-12-22 21:14

    If your controller and model are in the same namespace, then what you want is

    controller_path.classify
    

    controller_path gives you the namespace; controller_name doesn't.

    For example, if your controller is

    Admin::RolesController
    

    then:

    controller_path.classify # "Admin::Role" # CORRECT
    controller_name.classify # "Role"        # INCORRECT
    
    0 讨论(0)
  • 2020-12-22 21:15

    This will do it:

    class HouseBuyersController < ApplicationController
    
      def index
        @model_name = controller_name.classify
      end
    
    end
    

    This is often needed when abstracting controller actions:

    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
    
    0 讨论(0)
提交回复
热议问题