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」を返しますありがとうございます!
Peter Ehrlich

1
ActiveSupport :: Inflectorはすばらしい
Jared Beck、

必要に応じて(この質問では詳細を指定していません)、controller_name.sub('_', ' ').titleize「ハウスバイヤー」を取得することができます。
user664833 '19

(モデルクラスを取得するための)ロジックを別のユーティリティメソッドに移動することをお勧めします。結果を定数に保存すると、アクセスを高速化できます。new.controller_name.classify.constantizeクラス定義で使用できます。
ケルビン

これは、どのコントローラーがそれから継承するかに応じて、アプリケーションコントローラーでも機能することは注目に値します。
weltschmerz 2013

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

... @model_nameインスタンス変数で「HouseBuyer」を取得します。

繰り返しになりますが、これは「HouseBuyersController」が「HouseBuyer」モデルのみを処理するという大きな仮定を行います。


4

機能する名前空間の場合:

def resource_class
 controller_path.classify.constantize
end

0

これは、コードが従わないように見えるデフォルトのMVCを使用している場合は不可能です。あなたのコントローラーはモデルのようですが、たぶんあなたはそこにタイプを持っています。とにかく、コントローラーとモデルは基本的にRails MVCで分離されているため、コントローラーはそれらが関連付けられているモデルを認識できません。

たとえば、postというモデルがあるとします。これは、posts_controllerコントローラーを持つことも、articles_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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.