Rails: как получить имя класса модели на основе имени класса контроллера?


Ответы:


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 - это круто
Джаред Бек

В зависимости от ваших потребностей (в этом вопросе не уточняются детали) вы можете 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

... даст вам "HouseBuyer" в вашей переменной экземпляра @model_name.

Опять же, здесь делается огромное предположение, что HouseBuyersController имеет дело только с моделями HouseBuyer.


4

Для работающих пространств имен:

def resource_class
 controller_path.classify.constantize
end

0

Это невозможно, если вы используете MVC по умолчанию, которому ваш код не следует. Ваш контроллер кажется моделью, но, может быть, у вас только что есть тип. В любом случае контроллеры и модели в Rails MVC принципиально разделены, поэтому контроллеры не могут знать, с какой моделью они связаны.

Например, у вас может быть модель с именем post. Это может быть контроллер posts_controller или такой контроллер, как article_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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.