Rails: Wie erhalte ich den Modellklassennamen basierend auf dem Controller-Klassennamen?


Antworten:


190

Dies wird es tun:

class HouseBuyersController < ApplicationController

  def index
    @model_name = controller_name.classify
  end

end

Dies wird häufig benötigt, wenn Controller-Aktionen abstrahiert werden:

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 # gibt "HouseBuyers" zurück, danke!
Peter Ehrlich

1
ActiveSupport :: Inflector ist fantastisch
Jared Beck

Abhängig von Ihren Bedürfnissen (diese Frage enthält keine Details) können Sie controller_name.sub('_', ' ').titleize"Hauskäufer" finden.
user664833

Es kann sinnvoll sein, die Logik (zum Abrufen der Modellklasse) in eine separate Dienstprogrammmethode zu verschieben. Noch besser, wenn das Ergebnis in einer Konstanten gespeichert wird, um den Zugriff zu beschleunigen. Sie können new.controller_name.classify.constantizein der Klassendefinition verwenden.
Kelvin

Ich denke, es ist erwähnenswert, dass dies sogar im Anwendungscontroller funktioniert, je nachdem, welcher Controller davon erbt.
Weltschmerz

40

Wenn sich Ihr Controller und Ihr Modell im selben Namespace befinden, möchten Sie Folgendes

controller_path.classify

controller_path gibt Ihnen den Namespace; controller_namenicht.

Zum Beispiel, wenn Ihr Controller ist

Admin::RolesController

dann:

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

6

Es ist ein bisschen wie ein Hack, aber wenn Ihr Modell nach Ihrem Controllernamen benannt ist, dann:

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

... würde Ihnen "HouseBuyer" in Ihrer Instanzvariablen @model_name geben.

Dies setzt wiederum eine große Annahme voraus, dass "HouseBuyersController" nur "HouseBuyer" -Modelle behandelt.


4

Für funktionierende Namespaces:

def resource_class
 controller_path.classify.constantize
end

0

Dies ist nicht möglich, wenn Sie die Standard-MVC verwenden, der Ihr Code nicht zu folgen scheint. Ihr Controller scheint ein Modell zu sein, aber vielleicht haben Sie dort gerade einen Typ. Auf jeden Fall sind Controller und Modelle in Rails MVC grundsätzlich getrennt, sodass Controller nicht wissen können, welchem ​​Modell sie zugeordnet sind.

Zum Beispiel könnten Sie ein Modell namens post haben. Dies kann einen Controller posts_controller oder einen Controller wie articles_controller haben. Rails kennt Modelle nur, wenn Sie den tatsächlichen Code in der Steuerung wie z

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

In Schienen-Standardsteuerungen gibt es keine Möglichkeit, das Modell zu kennen.


0

Die akzeptierte Lösung funktionierte bei mir nicht, da mein Controller und mein Modell einen Namespace hatten. Stattdessen habe ich die folgende Methode entwickelt:

def controllers_model
  (self.class.name.split('::')[0..-2] << controller_name.classify).join('::')
end
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.