Bagaimana cara membuat daftar semua metode untuk suatu objek di Ruby?

113

Bagaimana cara mendaftar semua metode yang aksesnya dimiliki objek tertentu?

Saya memiliki @current_userobjek, yang ditentukan dalam pengontrol aplikasi:

def current_user
  @current_user ||= User.find(session[:user_id]) if session[:user_id]
end

Dan ingin melihat metode apa yang tersedia untuk saya di file tampilan. Secara khusus, saya ingin melihat metode apa yang :has_manydisediakan oleh sebuah asosiasi. (Saya tahu apa yang :has_many harus disediakan, tetapi ingin memeriksanya.)

Beladau
sumber
Untuk memperjelas, Anda ingin metode yang dapat dipanggil aktif @current_user?
Andrew Marshall
@Dirk, selamat datang di stackoverflow! Ingatlah untuk "memeriksa" jawaban yang paling menjawab pertanyaan Anda. Juga berikan suara positif untuk jawaban apa pun, untuk pertanyaan apa pun, yang menurut Anda berguna / berguna.
Larry K

Jawaban:

211

Berikut ini akan mencantumkan metode yang dimiliki kelas Pengguna yang tidak memiliki kelas Objek dasar ...

>> User.methods - Object.methods
=> ["field_types", "maximum", "create!", "active_connections", "to_dropdown",
    "content_columns", "su_pw?", "default_timezone", "encode_quoted_value", 
    "reloadable?", "update", "reset_sequence_name", "default_timezone=", 
    "validate_find_options", "find_on_conditions_without_deprecation", 
    "validates_size_of", "execute_simple_calculation", "attr_protected", 
    "reflections", "table_name_prefix", ...

Perhatikan bahwa methodsini adalah metode untuk Kelas dan untuk instance Kelas.

Berikut metode yang dimiliki kelas Pengguna saya yang tidak ada di kelas dasar ActiveRecord:

>> User.methods - ActiveRecord::Base.methods
=> ["field_types", "su_pw?", "set_login_attr", "create_user_and_conf_user", 
    "original_table_name", "field_type", "authenticate", "set_default_order",
    "id_name?", "id_name_column", "original_locking_column", "default_order",
    "subclass_associations",  ... 
# I ran the statements in the console.

Perhatikan bahwa metode yang dibuat sebagai hasil dari (banyak) hubungan has_many yang ditentukan di kelas Pengguna tidak ada dalam hasil methodspanggilan.

Ditambahkan Perhatikan bahwa: has_many tidak menambahkan metode secara langsung. Sebagai gantinya, mesin ActiveRecord menggunakan Ruby method_missingdan responds_toteknik untuk menangani pemanggilan metode dengan cepat. Akibatnya, metode tersebut tidak dicantumkan dalam methodshasil metode.

Larry K
sumber
2
Meskipun itu mungkin tidak lengkap karena beberapa metode hanya dibuat ketika method_missing dipanggil (misalnya, pencari dinamis)
Frederick Cheung
jika saya mencoba responds_to? Saya mendapatkan metode kesalahan yang hilang. Saya menjalankan ini di dalam application.html.erb
Dirk
@ Dirk - mungkin metodenya tidak ada ... Saya sarankan Anda mengajukan pertanyaan baru di mana Anda menunjukkan apa definisi Kelas AR Anda dan kemudian bertanya tentang metode spesifik yang menurut Anda: has_many harus disediakan. Juga apakah Anda memiliki kecocokan: milik_to? Aturan kapitalisasi dan pluralisasi Rails untuk AR telah menyesatkan banyak orang ...
Larry K
@Lar. Terima kasih - Saya bisa mendapatkan daftar dengan .to_yaml. Ini terlihat seperti ini: --- -: sketches -: sketch_ids -: sketches = -: sketch_ids = -: before_add_for_sketches -: before_add_for_sketches? <banyak dihilangkan> ........ bagaimana cara mengakses metode tersebut? (mengarahkan saya ke dokumentasi juga dihargai :)
Dirk
The docs untuk: menunjukkan has_many banyak metode yang ditambahkan. Yang lainnya baru untuk versi Rails yang lebih baru. Ini termasuk "before_add_for" dll. Mereka adalah "Association Callbacks" - lihat bagian itu dari dokumen
Larry K
9

Modul # instance_methods

Mengembalikan larik yang berisi nama metode instance publik dan dilindungi di penerima. Untuk modul, ini adalah metode publik dan dilindungi; untuk kelas, mereka adalah metode instance (bukan tunggal). Tanpa argumen, atau dengan argumen yang salah, metode instance dalam mod dikembalikan, jika tidak, metode dalam superclass mod dan mod dikembalikan.

module A
  def method1()  end
end
class B
  def method2()  end
end
class C < B
  def method3()  end
end

A.instance_methods                #=> [:method1]
B.instance_methods(false)         #=> [:method2]
C.instance_methods(false)         #=> [:method3]
C.instance_methods(true).length   #=> 43
clyfe
sumber
6

Atau hanya User.methods(false)mengembalikan hanya metode yang ditentukan dalam kelas itu.

Ruto Collins
sumber
4

Anda dapat melakukan

current_user.methods

Untuk daftar yang lebih baik

puts "\n\current_user.methods : "+ current_user.methods.sort.join("\n").to_s+"\n\n"
Andreas Lyngstad
sumber
3

Bagaimana dengan salah satunya?

object.methods.sort
Class.methods.sort
Michael Frederick
sumber
1

Misalkan Pengguna memiliki banyak Postingan:

u = User.first
u.posts.methods
u.posts.methods - Object.methods
Marek Příhoda
sumber
1

Untuk menjelaskan jawaban @ clyfe. Anda bisa mendapatkan daftar metode instance Anda menggunakan kode berikut (dengan asumsi Anda memiliki Kelas Objek bernama "Parser"):

Parser.new.methods - Object.new.methods
Jared Menard
sumber
1

Jika Anda mencari daftar metode yang merespons dengan sebuah instance (dalam kasus Anda @current_user). Menurut metode dokumentasi ruby

Menampilkan daftar nama metode publik dan metode objek yang dilindungi. Ini akan mencakup semua metode yang dapat diakses di leluhur obj. Jika parameter opsional salah, ia mengembalikan array metode tunggal publik dan dilindungi obj, array tidak akan menyertakan metode dalam modul yang termasuk dalam obj.

@current_user.methods
@current_user.methods(false) #only public and protected singleton methods and also array will not include methods in modules included in @current_user class or parent of it.

Atau, Anda juga dapat memeriksa apakah suatu metode dapat dipanggil pada suatu objek atau tidak ?.

@current_user.respond_to?:your_method_name

Jika Anda tidak menginginkan metode kelas induk, cukup kurangi metode kelas induk darinya.

@current_user.methods - @current_user.class.superclass.new.methods #methods that are available to @current_user instance.
Mukesh Kumar Gupta
sumber