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  

У рейкових стандартних контролерах немає способу дізнатися, що це за модель.


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.