Rails: come ottenere il nome della classe del modello in base al nome della classe del controller?


Risposte:


190

Questo lo farà:

class HouseBuyersController < ApplicationController

  def index
    @model_name = controller_name.classify
  end

end

Questo è spesso necessario quando si astraggono le azioni del controller:

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 # restituisce "HouseBuyers" grazie!
Peter Ehrlich

1
ActiveSupport :: Inflector è fantastico
Jared Beck,

A seconda delle tue esigenze, (questa domanda non specifica alcun dettaglio), puoi fare controller_name.sub('_', ' ').titleizeper ottenere "Acquirenti di case".
user664833

Potrebbe essere utile spostare la logica (per ottenere la classe del modello) in un metodo di utilità separato. Ancora meglio se il risultato viene memorizzato in una costante, per velocizzare l'accesso. È possibile utilizzare new.controller_name.classify.constantizenella definizione della classe.
Kelvin

Penso che valga la pena notare che questo funzionerà anche nel controller dell'applicazione a seconda di quale controller eredita da esso.
weltschmerz

40

Se il controller e il modello si trovano nello stesso spazio dei nomi, ciò che desideri è

controller_path.classify

controller_pathti dà lo spazio dei nomi; controller_namenon lo fa.

Ad esempio, se il tuo controller è

Admin::RolesController

poi:

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

6

È un po 'un trucco, ma se il tuo modello prende il nome del tuo controller, allora:

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

... ti darebbe "HouseBuyer" nella variabile di istanza @model_name.

Di nuovo, questo presuppone enormemente che "HouseBuyersController" si occupa solo di modelli "HouseBuyer".


4

Per gli spazi dei nomi funzionanti:

def resource_class
 controller_path.classify.constantize
end

0

Questo non è possibile se stai usando l'MVC predefinito, che il tuo codice non sembra seguire. Il tuo controller sembra essere un modello ma forse hai appena ottenuto un tipo lì. Ad ogni modo, controller e modelli sono fondamentalmente separati in Rails MVC, quindi i controller non possono sapere a quale modello sono associati.

Ad esempio potresti avere un modello chiamato post. Questo può avere un controller posts_controller o potrebbe avere un controller come articles_controller. Rails conosce i modelli solo quando definisci il codice effettivo nel controller come

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

Nei controller standard rails non c'è modo di sapere quale sia il modello.


0

La soluzione accettata non ha funzionato per me poiché il mio controller e il mio modello erano con spazio dei nomi. Invece, ho escogitato il seguente metodo:

def controllers_model
  (self.class.name.split('::')[0..-2] << controller_name.classify).join('::')
end
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.