Rails: Jak uzyskać nazwę klasy modelu na podstawie nazwy klasy kontrolera?


Odpowiedzi:


190

To zrobi to:

class HouseBuyersController < ApplicationController

  def index
    @model_name = controller_name.classify
  end

end

Jest to często potrzebne podczas wyodrębniania akcji kontrolera:

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 # zwraca "HouseBuyers" dzięki!
Peter Ehrlich

1
ActiveSupport :: Inflector jest niesamowity
Jared Beck

W zależności od Twoich potrzeb (to pytanie nie określa żadnych szczegółów), możesz zrobić, controller_name.sub('_', ' ').titleizeaby uzyskać „Kupujący dom”.
user664833

Dobrze byłoby przenieść logikę (w celu uzyskania klasy modelu) do oddzielnej metody narzędziowej. Jeszcze lepiej, jeśli wynik jest przechowywany w stałej, aby przyspieszyć dostęp. Możesz użyć new.controller_name.classify.constantizew definicji klasy.
Kelvin,

Myślę, że warto zauważyć, że to zadziała nawet w kontrolerze aplikacji w zależności od tego, który kontroler po nim dziedziczy.
weltschmerz

40

Jeśli kontroler i model znajdują się w tej samej przestrzeni nazw, to chcesz

controller_path.classify

controller_pathdaje przestrzeń nazw; controller_namenie.

Na przykład, jeśli twój kontroler to

Admin::RolesController

następnie:

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

6

To trochę hack, ale jeśli twój model nosi nazwę po nazwie kontrolera, to:

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

... da ci „HouseBuyer” w zmiennej instancji @model_name.

Ponownie, zakłada się, że „HouseBuyersController” obsługuje tylko modele „HouseBuyer”.


4

W przypadku działających przestrzeni nazw:

def resource_class
 controller_path.classify.constantize
end

0

Nie jest to możliwe, jeśli używasz domyślnego MVC, którego kod nie wydaje się przestrzegać. Twój kontroler wydaje się być modelem, ale może po prostu masz tam typ. W każdym razie kontrolery i modele są zasadniczo oddzielone w Rails MVC, więc kontrolery nie mogą wiedzieć, z którym modelem są skojarzone.

Na przykład możesz mieć model o nazwie post. Może to mieć kontroler post_controller lub może mieć kontroler taki jak artykuły_controller. Railsy wiedzą o modelach tylko wtedy, gdy zdefiniujesz rzeczywisty kod w kontrolerze, taki jak

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

W standardowych kontrolerach szynowych nie ma sposobu, aby dowiedzieć się, jaki jest model.


0

Zaakceptowane rozwiązanie nie zadziałało, ponieważ mój kontroler i model miały przestrzeń nazw. Zamiast tego wymyśliłem następującą metodę:

def controllers_model
  (self.class.name.split('::')[0..-2] << controller_name.classify).join('::')
end
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.