Rails: Bagaimana cara mendapatkan nama kelas model berdasarkan nama kelas controller?

99
class HouseBuyersController < ...
  def my_method
    # How could I get here the relevant model name, i.e. "HouseBuyer" ?
  end
end
Misha Moroshko
sumber

Jawaban:

190

Ini akan melakukannya:

class HouseBuyersController < ApplicationController

  def index
    @model_name = controller_name.classify
  end

end

Ini sering diperlukan saat mengabstraksi tindakan pengontrol:

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
malclocke
sumber
@model_name = controller_name.classify # mengembalikan "HouseBuyers" terima kasih!
Peter Ehrlich
1
ActiveSupport :: Inflector is awesome
Jared Beck
Bergantung pada kebutuhan Anda, (pertanyaan ini tidak menentukan detail apa pun), yang dapat Anda lakukan controller_name.sub('_', ' ').titleizeuntuk mendapatkan "Pembeli Rumah".
pengguna664833
Mungkin bagus untuk memindahkan logika (untuk mendapatkan kelas model) ke dalam metode utilitas terpisah. Lebih bagus lagi jika hasilnya disimpan secara konstan, untuk mempercepat akses. Anda dapat menggunakan new.controller_name.classify.constantizedefinisi kelas.
Kelvin
Saya pikir perlu dicatat bahwa ini bahkan akan berfungsi di pengontrol aplikasi tergantung pada pengontrol mana yang diwarisi darinya.
weltschmerz
40

Jika pengontrol dan model Anda berada di namespace yang sama, maka yang Anda inginkan adalah

controller_path.classify

controller_pathmemberi Anda namespace; controller_nametidak.

Misalnya, jika pengontrol Anda adalah

Admin::RolesController

kemudian:

controller_path.classify # "Admin::Role" # CORRECT
controller_name.classify # "Role"        # INCORRECT
Matt
sumber
6

Ini sedikit hack, tetapi jika model Anda dinamai sesuai nama pengontrol Anda, maka:

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

... akan memberi Anda "HouseBuyer" dalam variabel instance @model_name Anda.

Sekali lagi, ini membuat asumsi besar bahwa "HouseBuyersController" hanya berurusan dengan model "HouseBuyer".

Scott
sumber
4

Untuk ruang nama yang berfungsi:

def resource_class
 controller_path.classify.constantize
end
hachpai
sumber
0

Ini tidak mungkin jika Anda menggunakan MVC default, yang tampaknya tidak diikuti oleh kode Anda. Pengontrol Anda sepertinya model tetapi mungkin Anda baru saja mendapatkan tipe di sana. Bagaimanapun, pengontrol dan model pada dasarnya dipisahkan di Rails MVC sehingga pengontrol tidak dapat mengetahui model mana yang dikaitkan dengannya.

Misalnya Anda bisa memiliki model bernama post. Ini dapat memiliki pengontrol posts_controller atau dapat memiliki pengontrol seperti Articles_controller. Rails hanya tahu tentang model ketika Anda menentukan kode sebenarnya di controller seperti

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

Dalam pengontrol standar rel, tidak ada cara untuk mengetahui modelnya.

thenengah
sumber
0

Solusi yang diterima tidak berfungsi untuk saya karena pengontrol dan model saya diberi spasi nama. Sebagai gantinya, saya menemukan metode berikut:

def controllers_model
  (self.class.name.split('::')[0..-2] << controller_name.classify).join('::')
end
stoffus.dll
sumber