दिलचस्प पोस्ट
टैंसर प्रवाह में ग्रेडिएंट कटिंग की प्रभावी ढंग से कैसे लागू करें? एसएसआरएस 2008 आर 2 – एसएसआरएस 2012 – रिपोर्ट वीवर: सफारी और क्रोम में रिपोर्ट रिक्त हैं उद्देश्य सी संदेश प्रेषण तंत्र जांचें कि क्या एप्लिकेशन पहली बार चल रहा है एजेक्स सफलता कॉलबैक फ़ंक्शन के अंदर $ (इस) तक कैसे पहुंचें ggplot: पहल लेबल बदलने के लिए कैसे? क्या मैं CouchDB में लेनदेन और ताले कर सकता हूं? जावास्क्रिप्ट: अल्फ़ान्यूमेरिक स्ट्रिंग की प्राकृतिक प्रकार की लोकलहोस्ट पर फेसबुक एप्लिकेशन चलाना मेरी प्रीरीलेज़ ऐप iTunes Connect में एक हफ़्ते से अधिक समय तक "प्रोसेसिंग" रही है, क्या देता है? क्रॉस-ब्राउज़र (IE8-) जावास्क्रिप्ट के साथ संक्रमित शैली प्राप्त करें? क्या एक रिमोट रिपॉजिटरी में एक git छिपाने की जगह धक्का संभव है? कैसे एक सदस्य समारोह सूचक के माध्यम से कॉल करने के लिए? आईफोन से अग्रेषित जीओकोडिंग त्रुटि: पैकेज 'com.google.example' main.xml में विशेषता 'adSize' के लिए कोई संसाधन पहचानकर्ता नहीं मिला

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

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

मूल रूप से, क्या मैं इनकी पसंद कर सकता हूं: –

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

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

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

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

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

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

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

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

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

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

 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 

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

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

 Rails.application.eager_load! 

फिर:

 ActiveRecord::Base.descendants 

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

यह उन कक्षाओं पर भी काम कर सकता है जो ActiveRecord::Base से प्राप्त होते हैं, जैसे Rails 5 में ApplicationRecord , और केवल उप-धाराओं की वापसी करते हैं:

 ApplicationRecord.descendants 

यदि आप इस बारे में और जानना चाहते हैं कि यह कैसे किया जाता है, तो ActiveSupport :: DescendantsTracker की जांच करें।

बस किसी एक पर ठोकर खाई तो, मुझे एक और हल मिल गया है, डर पढ़ने या कक्षा कक्षा को बढ़ाने पर निर्भर नहीं है …

 ActiveRecord::Base.send :subclasses 

यह कक्षाओं की एक सरणी वापस करेगा तो आप फिर कर सकते हैं

 ActiveRecord::Base.send(:subclasses).map(&:name) 
 ActiveRecord::Base.connection.tables.map do |model| model.capitalize.singularize.camelize end 

वापस होगा

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

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

 model.classify.constantize.attribute_names 

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

 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

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

मेरा दृष्टिकोण काफी अलग है –

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

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

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

  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 %> 

यदि आप केवल कक्षा नाम चाहते हैं:

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

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

संपादित करें: @ एसजे 26 सही है, इससे पहले कि आप वंश को कॉल कर सकें, आपको इसे पहले चलाने की आवश्यकता है:

 Rails.application.eager_load! 

एक पंक्ति में: Dir['app/models/\*.rb'].map {|f| File.basename(f, '.*').camelize.constantize } Dir['app/models/\*.rb'].map {|f| File.basename(f, '.*').camelize.constantize }

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

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

या छोटा:

 ApplicationRecord.descendants.collect(&:name) 

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

 Rails.application.eager_load! 

सिर्फ एक पंक्ति में:

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

ActiveRecord::Base.connection.tables

मैं अभी तक टिप्पणी नहीं कर सकता, लेकिन मुझे लगता है कि एसजे 26 का जवाब सबसे ऊपर का जवाब होना चाहिए। बस एक संकेत:

 Rails.application.eager_load! unless Rails.configuration.cache_classes ActiveRecord::Base.descendants 
 Module.constants.select { |c| (eval c).is_a?(Class) && (eval c) < ActiveRecord::Base } 

रेल 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 

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

यहां एक समाधान है जिसे एक जटिल रेल ऐप (एक पॉवर स्क्वायर) के साथ ठीक किया गया है

 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 आदि का उपयोग करें।

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

 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}"}} 

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

 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 

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

इसलिए जो उपर्युक्त सहकर्मियों को कहते हैं, वे कम से कम प्रयास ऐसा करने के लिए पूरक हैं:

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

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

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

विधि Module.constantsModule.constants रिटर्न ( Module.constants से) स्थिरांक के बजाय symbols का एक संग्रह देता है, इसलिए, विधि Array#select Module.constants 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 

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

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

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

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

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

 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 
 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 

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

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

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

यह जांच सकता है

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

मान लें कि सभी मॉडल ऐप / मॉडल में हैं और आपके पास अपने सर्वर पर 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! तुलना में तेज़ Rails.application.eager_load! या Dir साथ प्रत्येक फाइल के माध्यम से पाशन

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

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

मैं इस उदाहरण को यहां फेंक रहा हूं अगर किसी को यह उपयोगी लगता है। समाधान इस उत्तर पर आधारित है 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 चला सकते हैं rake di:public_uids:generate