क्या आपके रेल एप्लिकेशन में सभी मॉडलों का संग्रह प्राप्त करने का एक तरीका है?


201

क्या कोई ऐसा तरीका है जिससे आप अपने रेल एप्लिकेशन में सभी मॉडलों का संग्रह प्राप्त कर सकते हैं?

मूल रूप से, क्या मैं ऐसा कर सकता हूं: -

Models.each do |model|
  puts model.class.name
end

1
यदि आपको रेल इंजन / रेल के मॉडल सहित सभी मॉडल एकत्र करने की आवश्यकता है, तो @jaime
आंद्रेई

रेल पर काम नहीं करता है 5.1
aks

जवाबों:


98

संपादित करें: टिप्पणियों और अन्य उत्तरों को देखें। इस एक की तुलना में होशियार उत्तर हैं! या सामुदायिक विकि के रूप में इसे बेहतर बनाने का प्रयास करें।

मॉडल खुद को एक मास्टर ऑब्जेक्ट में पंजीकृत नहीं करते हैं, इसलिए नहीं, रेल के पास मॉडल की सूची नहीं है।

लेकिन आप अभी भी अपने आवेदन के मॉडल निर्देशिका की सामग्री में देख सकते हैं ...

Dir.foreach("#{RAILS_ROOT}/app/models") do |model_path|
  # ...
end

संपादित करें: ActiveRecord :: बेस को विस्तारित करने वाली हर वर्ग की खोज के लिए रूबी प्रतिबिंब का उपयोग करने के लिए एक और (जंगली) विचार होगा। पता नहीं कैसे आप सभी वर्गों को सूचीबद्ध कर सकते हैं ...

संपादित करें: सिर्फ मनोरंजन के लिए, मुझे सभी वर्गों को सूचीबद्ध करने का एक तरीका मिला

Module.constants.select { |c| (eval c).is_a? Class }

EDIT: अंत में निर्देशिकाओं को देखे बिना सभी मॉडलों को सूचीबद्ध करने में सफल रहा

Module.constants.select do |constant_name|
  constant = eval constant_name
  if not constant.nil? and constant.is_a? Class and constant.superclass == ActiveRecord::Base
    constant
  end
end

यदि आप व्युत्पन्न वर्ग को भी संभालना चाहते हैं, तो आपको पूरी सुपरक्लास श्रृंखला का परीक्षण करना होगा। मैंने इसे क्लास क्लास में एक विधि जोड़कर किया:

class Class
  def extend?(klass)
    not superclass.nil? and ( superclass == klass or superclass.extend? klass )
  end
end

def models 
  Module.constants.select do |constant_name|
    constant = eval constant_name
    if not constant.nil? and constant.is_a? Class and constant.extend? ActiveRecord::Base
    constant
    end
  end
end

6
FYI करें, मैंने दोनों तरीकों को केवल मनोरंजन के लिए समय दिया। निर्देशिकाओं को देखते हुए, कक्षाओं को खोजने की तुलना में तेज़ी से परिमाण का एक क्रम है। यह शायद स्पष्ट था, लेकिन अब आप जानते हैं :)
एडवर्ड एंडरसन

9
इसके अलावा, यह ध्यान रखना महत्वपूर्ण है कि स्थिरांक विधियों के माध्यम से मॉडल की खोज में कुछ भी शामिल नहीं होगा जिसे ऐप शुरू होने के बाद से संदर्भित नहीं किया गया है, क्योंकि यह केवल मॉडल को मांग पर लोड करता है।
एडवर्ड एंडरसन

4
मैं constant कर्नेल.कॉन्स्ट_गस्त कन्टेन_नाम ’को constant इवल कंटैस्ट_नाम’ पसंद करता हूं।
जेरेमी विंग्स

3
RAILS_ROOTअब रेल 3 में उपलब्ध नहीं है। इसके बजाय, उपयोगDir.glob(Rails.root.join('app/models/*'))
fanaugen

1
वास्तव में, मॉडल खुद को ActiveRecord::Baseअब के वंश के रूप में पंजीकृत करते हैं, इसलिए यदि आप सभी मॉडलों को उत्सुक करते हैं तो आप उन्हें आसानी से प्रसारित कर सकते हैं - नीचे अपना उत्तर देखें।
sj26

393

रेल 3, 4 और 5 का पूरा उत्तर है:

यदि cache_classesबंद है (डिफ़ॉल्ट रूप से यह विकास में बंद है, लेकिन उत्पादन में):

Rails.application.eager_load!

फिर:

ActiveRecord::Base.descendants

यह आपके आवेदन में सभी मॉडलों को सुनिश्चित करता है, भले ही वे कहाँ हैं, लोड किए गए हैं, और आपके द्वारा उपयोग किए जा रहे किसी भी रत्न को भी प्रदान किया जाता है।

यह उन वर्गों पर भी काम करना चाहिए ActiveRecord::Base, जो वंशानुक्रम में आते हैं , जैसे ApplicationRecordकि रेल 5, और केवल उसी श्रेणी में आते हैं जो वंश का उप योग है:

ApplicationRecord.descendants

यदि आप यह जानना चाहते हैं कि यह कैसे किया जाता है, तो ActiveSupport :: DescendantsTracker देखें


33
बहुत बढ़िया! यह स्वीकृत उत्तर होना चाहिए। किसी को भी एक रेक कार्य में इस का उपयोग कर के लिए: करें कि आपके काम पर निर्भर :environmentके लिए eager_load!काम करने के लिए।
जो लिस

1
या, थोड़ा तेज विकल्प के रूप में Rails.application.eager_load!, आप केवल मॉडलों को लोड कर सकते हैं:Dir.glob(Rails.root.join('app/models/*')).each do |x| require x end
Ajedi32

5
@ Ajedi32 जो पूर्ण नहीं है, मॉडल को उन निर्देशिकाओं के बाहर परिभाषित किया जा सकता है, खासकर जब मॉडल वाले इंजन का उपयोग कर रहे हों। थोड़ा बेहतर, कम से कम ग्लोब सभी Rails.paths["app/models"].existentनिर्देशिका। पूरे आवेदन को लोड करने वाला उत्सुक अधिक पूर्ण उत्तर है और यह सुनिश्चित करेगा कि मॉडल को परिभाषित करने के लिए बिल्कुल कहीं नहीं बचा है।
sj26

2
मुझे पता है कि sj26 का क्या मतलब है, लेकिन शायद थोड़ी गलती है: जहाँ तक मुझे विकास के माहौल में पता है cache_classes बंद है (झूठा) इसीलिए आपको सभी मॉडलों का उपयोग करने के लिए एप्लिकेशन को मैन्युअल रूप से लोड करने की आवश्यकता है। यहाँ समझाया गया है
masciugo

3
@ Ajedi32 फिर, पूरा जवाब नहीं। यदि आप केवल मॉडलों के लिए उत्सुक होना चाहते हैं, तो प्रयास करें:Rails.application.paths["app/models"].eager_load!
sj26

119

बस अगर कोई इस पर ठोकर खाता है, तो मुझे एक और उपाय मिल गया है, न कि डीआईआर पढ़ने पर भरोसा करना या क्लास क्लास का विस्तार करना ...

ActiveRecord::Base.send :subclasses

यह कक्षाओं की एक सरणी लौटाएगा। तो आप कर सकते हैं

ActiveRecord::Base.send(:subclasses).map(&:name)

8
आप उपयोग क्यों नहीं करते, ActiveRecord::Base.subclassesलेकिन उपयोग करना है send? इसके अलावा, ऐसा लगता है कि आपको मॉडल दिखाने से पहले उसे "स्पर्श" करना होगा, उदाहरण के लिए c = Category.newऔर यह दिखाई देगा। अन्यथा, यह नहीं होगा।
गैर

52
रेल 3 में, इसे बदल दिया गया हैActiveRecord::Base.descendants
टोबियास कोहेन

3
आपको "भेजें" का उपयोग करना होगा क्योंकि: उपवर्ग सदस्य संरक्षित है।
केविन रूड

11
रेल 3 टिप के लिए धन्यवाद। किसी और के लिए जो साथ आता है, आपको अभी भी मॉडल को "स्पर्श" करने की आवश्यकता है इससे पहले कि ActiveRecord::Base.descendantsवे उन्हें सूचीबद्ध करेंगे।
nfm

3
तकनीकी रूप से रेल 3 में आपके पास उपवर्ग और वंशज हैं, उनका मतलब अलग-अलग चीजों से है।
sj26

67
ActiveRecord::Base.connection.tables.map do |model|
  model.capitalize.singularize.camelize
end

वापस होगा

["Article", "MenuItem", "Post", "ZebraStripePerson"]

अतिरिक्त जानकारी यदि आप मॉडल के बिना ऑब्जेक्ट नाम पर एक विधि को कॉल करना चाहते हैं: स्ट्रिंग अज्ञात विधि या चर त्रुटियां इसका उपयोग करती हैं

model.classify.constantize.attribute_names

8
यह आपको सभी टेबल मिल जाएगा, न केवल मॉडल, क्योंकि कुछ टेबल में हमेशा संबंधित मॉडल नहीं होते हैं।
कोर्टिमेस

इस उत्तर को गलत माना जाना चाहिए क्योंकि यह मॉडल के बहुवचन नाम के अलावा तालिका के नाम को कॉन्फ़िगर करने के लिए संभव (और सामान्य रूप से विरासत में) है। यह उत्तर तब भी सही उत्तर देता है जब सेटअप डिफ़ॉल्ट कॉन्फ़िगरेशन से विचलित हो जाता है।
लॉरफॉन

कुछ मामलों में यह बेहतर काम करता है ActiveRecord::Base.send :subclasses- तालिका के नामों की तलाश एक अच्छा विचार है। मॉडल के नाम को स्वचालित रूप से उत्पन्न करने में समस्या हो सकती है क्योंकि लॉरफॉन का उल्लेख किया गया है।
Tilo

.capitalize.singularize.camelizeको प्रतिस्थापित किया जा सकता है .classify
मैक्सिम

34

मैंने इसे करने के तरीकों की तलाश की और इस तरह से चयन किया:

in the controller:
    @data_tables = ActiveRecord::Base.connection.tables

in the view:
  <% @data_tables.each do |dt|  %>
  <br>
  <%= dt %>
  <% end %>
  <br>

स्रोत: http://portfo.li/rails/348561-how-can-one-list-all-database-tables-from-one-project


1
यह एकमात्र तरीका है जिससे मैं सभी मॉडल प्राप्त कर सकता हूं, जिसमें ऐप में उपयोग किए गए रेल इंजन के मॉडल भी शामिल हैं। पारितोषिक के लिए धन्यवाद!
आंद्रेई

2
कुछ उपयोगी तरीके: ActiveRecord::Base.connection.tables.each{|t| begin puts "%s: %d" % [t.humanize, t.classify.constantize.count] rescue nil end}कुछ मॉडल सक्रिय नहीं हो सकते हैं इसलिए आपको इसे बचाने की आवश्यकता है।
आंद्रेई

2
@ आंद्रेई थोड़ा सा: model_classes = ActiveRecord::Base.connection.tables.collect{|t| t.classify.constantize rescue nil }.compact
मैक्स विलियम्स

30

के लिए Rails5 मॉडल हैं अब उपवर्गों की ApplicationRecordतो आपके एप्लिकेशन में सभी मॉडलों आप कर की सूची प्राप्त करने:

ApplicationRecord.descendants.collect { |type| type.name }

या कम:

ApplicationRecord.descendants.collect(&:name)

यदि आप देव मोड में हैं, तो आपको पहले मॉडल लोड करने की आवश्यकता होगी:

Rails.application.eager_load!

1
मैं इसे लेता हूं कि इसके लिए आवश्यकता होगी कि कक्षाएं पहले से ही भरी हुई हों और ऑटोलैडिंग सक्षम होने के साथ विकास के माहौल में अपूर्ण परिणाम दें। मैं नीचे नहीं जाऊंगा लेकिन शायद इसका उत्तर में उल्लेख किया जाना चाहिए।
लॉरफॉन

किराया पर्याप्त, अद्यतन
नीमर

मैं रेल 6.0.2 और उत्सुक_ लोड पर हूँ! कुछ भी नहीं बल्कि एक खाली सरणी को वापस करने के लिए वंशजों की विधि बनाई।
jgomo3

23

मुझे लगता है कि @ hnovick का समाधान एक अच्छा है यदि आपके पास टेबल-कम मॉडल नहीं हैं। यह समाधान विकास मोड में भी काम करेगा

हालांकि मेरा दृष्टिकोण बिलकुल अलग है -

ActiveRecord::Base.connection.tables.map{|x|x.classify.safe_constantize}.compact

वर्गीकरण को एक स्ट्रिंग से ठीक से कक्षा का नाम देने के लिए अच्छी तरह से माना जाता है । safe_constantize यह सुनिश्चित करता है कि आप बिना किसी अपवाद के इसे सुरक्षित रूप से एक वर्ग में बदल सकते हैं। यदि आपके पास डेटाबेस टेबल है, तो यह आवश्यक नहीं है। कॉम्पैक्ट ताकि एन्यूमरेशन में किसी भी निल्स को हटा दिया जाए।


3
वह भयानक है @ आदित्य संघी। मैं इसके बारे में नहीं जानता था safe_constantize
सिपाही 18'12

रेल के लिए 2.3.x, का उपयोग करें: ActiveRecord :: Base.connection.tables.map {| x | x.classify.constantize Rescue nil} .compact
iheggie

@iheggie आमतौर पर यह पोस्ट करने से बेहतर है कि इसे मौजूदा पोस्ट में संपादित करने से अलग उत्तर दिया जाए।
1:30 बजे पोचूच

धन्यवाद, मैंने पाया कि आप सबसे अच्छा मुझे #adiya के लिए अनुकूल का जवाब
जादूगर

21

यदि आप सिर्फ कक्षा के नाम चाहते हैं:

ActiveRecord::Base.descendants.map {|f| puts f}

बस इसे रेल कंसोल में चलाएं, इससे ज्यादा कुछ नहीं। सौभाग्य!

EDIT: @ sj26 सही है, आपको वंशज कहने से पहले इसे पहले चलाना होगा:

Rails.application.eager_load!

बस मुझे जो चाहिए था। धन्यवाद!
सूर्यास्त

के mapसाथ बुला puts? मुझे यह बात ActiveRecord::Base.descendants.map(&:model_name)
नूनो कोस्टा

आप इसे इस तरह से कर सकते हैं, लेकिन वे एक एकल सरणी में होंगे, लाइन द्वारा लाइन के बजाय, प्रारूप को पढ़ने में बहुत आसान है।
जॉर्डन माइकल रशिंग

17

यह मेरे लिए काम करने लगता है:

  Dir.glob(RAILS_ROOT + '/app/models/*.rb').each { |file| require file }
  @models = Object.subclasses_of(ActiveRecord::Base)

रेल केवल मॉडल का उपयोग करने पर लोड करती है, इसलिए Dir.glob लाइन को मॉडल निर्देशिका में सभी फ़ाइलों की आवश्यकता होती है।

एक बार जब आपके पास एक सरणी में मॉडल होते हैं, तो आप वह कर सकते हैं जो आप सोच रहे थे (उदाहरण के लिए कोड में):

<% @models.each do |v| %>
  <li><%= h v.to_s %></li>
<% end %>

धन्यवाद भुसेल मैं मूल रूप से दृष्टिकोण की इस शैली के साथ गया था, लेकिन विंसेंट ने उस समाधान का उपयोग करके समाप्त कर दिया, जैसा कि ऊपर पोस्ट किया गया था, जिसका मतलब था कि मुझे फ़ाइल का नाम "मॉडलाइज़" करने की आवश्यकता नहीं थी (यानी किसी भी _ को बाहर निकाल दें, प्रत्येक शब्द को कैपिटल करें और फिर जुड़ें! उन्हें दोबारा)।
mr_urf

उपनिर्देशिका के साथ:...'/app/models/**/*.rb'
आर्टमेव

Object.subclasses_of को v2.3.8 के बाद निकाला गया है।
डेविड जे।

11

एक लाइन पर: Dir['app/models/\*.rb'].map {|f| File.basename(f, '.*').camelize.constantize }


7
यह एक अच्छा है, क्योंकि रेल 3 में, आपके मॉडल डिफ़ॉल्ट रूप से ऑटो-लोड नहीं होते हैं, इसलिए उपरोक्त कई तरीके सभी संभव मॉडल वापस नहीं करेंगे। मेरा क्रमचय भी प्लगइन्स और उपनिर्देशिकाओं में मॉडल को पकड़ता है:Dir['**/models/**/*.rb'].map {|f| File.basename(f, '.*').camelize.constantize }
wbharding

2
@wharding यह बहुत अच्छा है, लेकिन जब यह मेरे rspec मॉडल परीक्षणों के नामों को स्थिर करने की कोशिश करता है तो यह गलत हो जाता है। ;-)
Ajedi32

@ अच्छा समाधान है, लेकिन यह तब टूट जाता है जब आपके पास नामांकित मॉडल होते हैं
मार्कस मंसूर

10

ActiveRecord::Base.connection.tables


तालिका में सभी कॉलमों को सूचीबद्ध करने के लिए एक अच्छा फॉलोअप <table_name> .column_names है। तो आपकी उपयोगकर्ता तालिका के लिए आप User.column_names
Mark Locklear

यह आपको सभी टेबल मिल जाएगा, न केवल मॉडल, क्योंकि कुछ टेबल में हमेशा संबंधित मॉडल नहीं होते हैं।
कोर्टिम्स

7

केवल एक पंक्ति में:

 ActiveRecord::Base.subclasses.map(&:name)

2
यह मेरे लिए सभी मॉडल नहीं दिखाता है। यकीन नहीं है कि क्यों। यह वास्तव में एक जोड़ी है।
कोर्टिम्स

1
मेरे लिए काम किया। 'बस थोड़ी देर के लिए सभी का जवाब है। उसे कुछ टाइम और दो।
बोल्डर_रूबी

2
संभवतः Rails.application.eager_load!विकास मोड में निष्पादन से पहले इसकी आवश्यकता है।
डेनिसपर्सप्लिन

7

मैं अभी तक टिप्पणी नहीं कर सकता, लेकिन मुझे लगता है कि sj26 उत्तर शीर्ष उत्तर होना चाहिए। बस एक संकेत:

Rails.application.eager_load! unless Rails.configuration.cache_classes
ActiveRecord::Base.descendants

6

रेल्स 6 के साथ , Zetiwerk डिफ़ॉल्ट कोड लोडर बन गया।

उत्सुक लोडिंग के लिए, प्रयास करें:

Zeitwerk::Loader.eager_load_all

फिर

ApplicationRecord.descendants

5

हाँ, ऐसे कई तरीके हैं जिनसे आप सभी मॉडल नामों को पा सकते हैं लेकिन मैंने अपने रत्न मॉडल_इनफो में जो किया है, वह आपको सभी मॉडलों को रत्नों में शामिल कर देगा।

array=[], @model_array=[]
Rails.application.eager_load!
array=ActiveRecord::Base.descendants.collect{|x| x.to_s if x.table_exists?}.compact
array.each do |x|
  if  x.split('::').last.split('_').first != "HABTM"
    @model_array.push(x)
  end
  @model_array.delete('ActiveRecord::SchemaMigration')
end

तो बस यह प्रिंट करें

@model_array

3

यह रेल 3.2.18 के लिए काम करता है

Rails.application.eager_load!

def all_models
  models = Dir["#{Rails.root}/app/models/**/*.rb"].map do |m|
    m.chomp('.rb').camelize.split("::").last
  end
end

उस Rails.application.eager_load के लिए upvolt! विचार
समकक्ष 8

3

सभी रेलों को प्री-लोड करने से बचने के लिए, आप यह कर सकते हैं:

Dir.glob("#{Rails.root}/app/models/**/*.rb").each {|f| require_dependency(f) }

आवश्यकता_ निर्भरता (एफ) वही है जो Rails.application.eager_load! उपयोग करता है। यह पहले से ही आवश्यक फ़ाइल त्रुटियों से बचना चाहिए।

फिर आप एआर मॉडल को सूचीबद्ध करने के लिए सभी तरह के समाधानों का उपयोग कर सकते हैं, जैसे ActiveRecord::Base.descendants


2
Module.constants.select { |c| (eval c).is_a?(Class) && (eval c) < ActiveRecord::Base }

TypeError को फेंकता है: सांत्वना में String में Symbol का कोई निहित रूपांतरण नहीं।
स्नोबॉलज

1

यहाँ एक समाधान है जिसे एक जटिल रेल एप्लिकेशन (एक पावरिंग स्क्वायर) से जोड़ा गया है

def all_models
  # must eager load all the classes...
  Dir.glob("#{RAILS_ROOT}/app/models/**/*.rb") do |model_path|
    begin
      require model_path
    rescue
      # ignore
    end
  end
  # simply return them
  ActiveRecord::Base.send(:subclasses)
end

इस थ्रेड में उत्तरों का सबसे अच्छा हिस्सा लेता है और उन्हें सबसे सरल और सबसे गहन समाधान में जोड़ता है। यह उन मामलों को संभालता है जहां आपके मॉडल उपनिर्देशिका में हैं, set_table_name आदि का उपयोग करें।


1

बस इस एक के पार आया, क्योंकि मुझे सभी मॉडलों को उनकी विशेषताओं के साथ प्रिंट करने की आवश्यकता है (@ आदित्य संघी की टिप्पणी पर निर्मित):

ActiveRecord::Base.connection.tables.map{|x|x.classify.safe_constantize}.compact.each{ |model| print "\n\n"+model.name; model.new.attributes.each{|a,b| print "\n#{a}"}}

1

इसने मेरे लिए काम किया। उपरोक्त सभी पोस्ट के लिए विशेष धन्यवाद। यह आपके सभी मॉडलों का एक संग्रह लौटना चाहिए।

models = []

Dir.glob("#{Rails.root}/app/models/**/*.rb") do |model_path|
  temp = model_path.split(/\/models\//)
  models.push temp.last.gsub(/\.rb$/, '').camelize.constantize rescue nil
end

1

Railsलागू विधि descendantsहै, लेकिन मॉडल जरूरी नहीं कि कभी से विरासत ActiveRecord::Base, उदाहरण के लिए, वर्ग कि मॉड्यूल शामिलActiveModel::Model एक मॉडल के रूप में एक ही व्यवहार करना होगा, न कि केवल एक मेज से लिंक किया जाएगा है।

इसलिए ऊपर के सहयोगियों का कहना है कि पूरक, थोड़ा प्रयास यह करेगा:

Classरूबी की कक्षा के बंदर पैच :

class Class
  def extends? constant
    ancestors.include?(constant) if constant != self
  end
end

और विधि models, पूर्वजों सहित, इस प्रकार है:

विधि स्थिरांक के बजाय Module.constants(सतही रूप से) संग्रह करती है symbols, इसलिए, विधि Array#selectको इस बंदर के पैच की तरह प्रतिस्थापित किया जा सकता है Module:

class Module

  def demodulize
    splitted_trail = self.to_s.split("::")
    constant = splitted_trail.last

    const_get(constant) if defines?(constant)
  end
  private :demodulize

  def defines? constant, verbose=false
    splitted_trail = constant.split("::")
    trail_name = splitted_trail.first

    begin
      trail = const_get(trail_name) if Object.send(:const_defined?, trail_name)
      splitted_trail.slice(1, splitted_trail.length - 1).each do |constant_name|
        trail = trail.send(:const_defined?, constant_name) ? trail.const_get(constant_name) : nil
      end
      true if trail
    rescue Exception => e
      $stderr.puts "Exception recovered when trying to check if the constant \"#{constant}\" is defined: #{e}" if verbose
    end unless constant.empty?
  end

  def has_constants?
    true if constants.any?
  end

  def nestings counted=[], &block
    trail = self.to_s
    collected = []
    recursivityQueue = []

    constants.each do |const_name|
      const_name = const_name.to_s
      const_for_try = "#{trail}::#{const_name}"
      constant = const_for_try.constantize

      begin
        constant_sym = constant.to_s.to_sym
        if constant && !counted.include?(constant_sym)
          counted << constant_sym
          if (constant.is_a?(Module) || constant.is_a?(Class))
            value = block_given? ? block.call(constant) : constant
            collected << value if value

            recursivityQueue.push({
              constant: constant,
              counted: counted,
              block: block
            }) if constant.has_constants?
          end
        end
      rescue Exception
      end

    end

    recursivityQueue.each do |data|
      collected.concat data[:constant].nestings(data[:counted], &data[:block])
    end

    collected
  end

end

के बंदर पैच String

class String
  def constantize
    if Module.defines?(self)
      Module.const_get self
    else
      demodulized = self.split("::").last
      Module.const_get(demodulized) if Module.defines?(demodulized)
    end
  end
end

और, अंत में, मॉडल विधि

def models
  # preload only models
  application.config.eager_load_paths = model_eager_load_paths
  application.eager_load!

  models = Module.nestings do |const|
    const if const.is_a?(Class) && const != ActiveRecord::SchemaMigration && (const.extends?(ActiveRecord::Base) || const.include?(ActiveModel::Model))
  end
end

private

  def application
    ::Rails.application
  end

  def model_eager_load_paths
    eager_load_paths = application.config.eager_load_paths.collect do |eager_load_path|
      model_paths = application.config.paths["app/models"].collect do |model_path|
        eager_load_path if Regexp.new("(#{model_path})$").match(eager_load_path)
      end
    end.flatten.compact
  end

1
Dir.foreach("#{Rails.root.to_s}/app/models") do |model_path|
  next unless model_path.match(/.rb$/)
  model_class = model_path.gsub(/.rb$/, '').classify.constantize
  puts model_class
end

इससे आपको अपने प्रोजेक्ट पर सभी मॉडल कक्षाएं मिलेंगी।


0
def load_models_in_development
  if Rails.env == "development"
    load_models_for(Rails.root)
    Rails.application.railties.engines.each do |r|
      load_models_for(r.root)
    end
  end
end

def load_models_for(root)
  Dir.glob("#{root}/app/models/**/*.rb") do |model_path|
    begin
      require model_path
    rescue
      # ignore
    end
  end
end

0

मैंने इन उत्तरों में से बहुत से लोगों को असफलता की कोशिश की है 4 रेल में (वाह उन्होंने भगवान के लिए एक या दो चीजें बदल दीं) मैंने खुद को जोड़ने का फैसला किया। जो ActiveRecord :: Base.connection कहलाते हैं और तालिका के नामों पर काम करते हैं, लेकिन मुझे जो परिणाम चाहिए, वह नहीं मिला क्योंकि मैंने कुछ मॉडल (ऐप / मॉडल के अंदर एक फ़ोल्डर में) छिपा दिया है, जिसे मैं नहीं चाहता था हटाएँ:

def list_models
  Dir.glob("#{Rails.root}/app/models/*.rb").map{|x| x.split("/").last.split(".").first.camelize}
end

मैंने एक इनिशियलाइज़र में डाल दिया है और इसे कहीं से भी कॉल कर सकता है। अनावश्यक माउस-उपयोग को रोकता है।


0

यह देख सकते हैं

@models = ActiveRecord::Base.connection.tables.collect{|t| t.underscore.singularize.camelize}

0

सभी मॉडलों को एप्लिकेशन / मॉडल में मान लिया गया है और आपके पास अपने सर्वर (मामलों के बहुमत) पर grep और awk है,

# extract lines that match specific string, and print 2nd word of each line
results = `grep -r "< ActiveRecord::Base" app/models/ | awk '{print $2}'`
model_names = results.split("\n")

यह Rails.application.eager_load!प्रत्येक फ़ाइल के माध्यम से तेज़ या लूपिंग करता है Dir

संपादित करें:

इस पद्धति का नुकसान यह है कि यह उन मॉडलों को याद करता है जो अप्रत्यक्ष रूप से ActiveRecord (जैसे FictionalBook < Book) से विरासत में मिले हैं । सबसे सुरक्षित तरीका है Rails.application.eager_load!; ActiveRecord::Base.descendants.map(&:name), भले ही यह थोड़े धीमे हो।


0

मैं सिर्फ इस उदाहरण को यहाँ फेंक रहा हूँ अगर किसी को यह उपयोगी लगता है। समाधान इस उत्तर https://stackoverflow.com/a/10712838/473040 पर आधारित है ।

मान लें कि आपके पास एक कॉलम है public_uidजिसे बाहरी दुनिया के लिए प्राथमिक आईडी के रूप में उपयोग किया जाता है (आप यह जान सकते हैं कि आप यहां ऐसा क्यों करना चाहते हैं )

अब कहते हैं कि आपने मौजूदा मॉडल के गुच्छा पर इस क्षेत्र को पेश किया है और अब आप उन सभी रिकॉर्डों को फिर से बनाना चाहते हैं जो अभी तक सेट नहीं हैं। आप ऐसा कर सकते हैं

# lib/tasks/data_integirity.rake
namespace :di do
  namespace :public_uids do
    desc "Data Integrity: genereate public_uid for any model record that doesn't have value of public_uid"
    task generate: :environment do
      Rails.application.eager_load!
      ActiveRecord::Base
        .descendants
        .select {|f| f.attribute_names.include?("public_uid") }
        .each do |m| 
          m.where(public_uid: nil).each { |mi| puts "Generating public_uid for #{m}#id #{mi.id}"; mi.generate_public_uid; mi.save }
      end 
    end 
  end 
end

अब आप चला सकते हैं rake di:public_uids:generate

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.