আপনার রেলস অ্যাপ্লিকেশনে সমস্ত মডেলের সংগ্রহ পাওয়ার কী উপায় আছে?


201

এমন কোনও উপায় আছে যে আপনি আপনার রেল অ্যাপগুলিতে সমস্ত মডেলের সংগ্রহ পেতে পারেন?

মূলত, আমি কি এর পছন্দগুলি করতে পারি:

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

1
আপনার যদি রেল ইঞ্জিন / রেলটির মডেল সহ সমস্ত মডেল সংগ্রহ করার দরকার হয় তবে @ জাইমে
আন্দ্রেই

উত্তর:


98

সম্পাদনা: মন্তব্য এবং অন্যান্য উত্তর দেখুন। এই এক চেয়ে স্মার্ট উত্তর আছে! অথবা সম্প্রদায় উইকি হিসাবে এটিকে উন্নত করার চেষ্টা করুন।

মডেলগুলি কোনও মাস্টার অবজেক্টে নিজেকে নিবন্ধন করে না, সুতরাং না, মডেলগুলির তালিকায় নেই রেয়েলগুলি।

তবে আপনি এখনও আপনার অ্যাপ্লিকেশনটির মডেল ডিরেক্টরিগুলির বিষয়বস্তুটিতে সন্ধান করতে পারেন ...

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

সম্পাদনা: আরেকটি (বন্য) ধারণাটি হ'ল অ্যাক্টিভেকর্ড :: বেস প্রসারিত প্রতিটি শ্রেণীর সন্ধানের জন্য রুবি প্রতিবিম্ব ব্যবহার করা। আপনি কীভাবে সমস্ত ক্লাস তালিকাভুক্ত করতে পারেন তা জানেন না ...

সম্পাদনা: কেবল মজা করার জন্য, আমি সমস্ত ক্লাসের তালিকা করার একটি উপায় খুঁজে পেয়েছি

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

6
এফওয়াইআই, আমি উভয় পদ্ধতি কেবল মজাদার জন্য সময়সীমা নির্ধারণ করেছি। ডিরেক্টরিগুলি সন্ধান করা ক্লাসগুলি সন্ধানের চেয়ে দ্রুততর মানের একটি ক্রম। এটি সম্ভবত সুস্পষ্ট ছিল, তবে এখন আপনি জানেন :)
এডওয়ার্ড অ্যান্ডারসন

9
এছাড়াও, এটি লক্ষণীয় গুরুত্বপূর্ণ যে ধ্রুবক পদ্ধতিগুলির মাধ্যমে মডেলগুলি অনুসন্ধান করা অ্যাপ্লিকেশন শুরু হওয়ার পরে রেফারেন্স হয়নি এমন কোনও কিছু অন্তর্ভুক্ত করবে না, কারণ এটি কেবলমাত্র চাহিদা অনুযায়ী মডেলগুলি লোড করে।
এডওয়ার্ড অ্যান্ডারসন

4
আমি 'কর্নাল। কনস্ট্যান্ট_গেট ধ্রুবক_নাম' 'ইভাল ধ্রুবক_নাম' থেকে পছন্দ করি।
জেরেমি ওয়েথার্স

3
RAILS_ROOT3 টি আর Dir.glob(Rails.root.join('app/models/*'))
রেলগুলিতে

1
প্রকৃতপক্ষে, মডেলগুলি ActiveRecord::Baseএখনকার বংশধর হিসাবে নিজেকে নিবন্ধিত করে , তাই আপনি যদি সমস্ত মডেলকে আগ্রহী করেন তবে আপনি সেগুলি সহজেই পুনরাবৃত্তি করতে পারেন - নীচে আমার উত্তর দেখুন।
sj26

393

3, 4 এবং 5 রেলের পুরো উত্তরটি হ'ল:

যদি cache_classesবন্ধ থাকে (ডিফল্টরূপে এটি বিকাশে বন্ধ থাকে তবে উত্পাদনে থাকে):

Rails.application.eager_load!

তারপর:

ActiveRecord::Base.descendants

এটি নিশ্চিত করে তোলে যে আপনার অ্যাপ্লিকেশনের সমস্ত মডেল তারা যেখানেই থাকুক না কেন, বোঝাই হয়েছে এবং মডেল সরবরাহকারী কোনও রত্নও লোড হয়েছে।

এটি ক্লাসগুলিতেও কাজ করবে যা উত্তরাধিকার সূত্রে প্রাপ্ত হয় ActiveRecord::Base, যেমন ApplicationRecord5 রেলের মতো , এবং কেবলমাত্র বংশধরদের সেই সাবট্রিকেই ফিরে আসতে পারে:

ApplicationRecord.descendants

এটি কীভাবে করা হয় সে সম্পর্কে আপনি যদি আরও জানতে চান তবে অ্যাক্টিভসপোর্ট :: ডেসেন্ডেন্টস ট্র্যাকার পরীক্ষা করে দেখুন ।


33
অসাধারণ! এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। এটি একটি রেক টাস্কে যে কেউ ব্যবহার করছে তার জন্য: কাজের :environmentজন্য আপনার টাস্ককে নির্ভর করুন eager_load!
জো লিস

1
অথবা এর সামান্য দ্রুত বিকল্প হিসাবে Rails.application.eager_load!আপনি কেবলমাত্র মডেলগুলি লোড করতে পারেন:Dir.glob(Rails.root.join('app/models/*')).each do |x| require x end
আজেদি 32

5
@ Ajedi32 যা সম্পূর্ণ নয়, মডেলগুলি সেই ডিরেক্টরিগুলির বাইরে নির্দিষ্ট করা যেতে পারে, বিশেষত যখন মডেলগুলির সাথে ইঞ্জিনগুলি ব্যবহার করা হয়। কিছুটা ভাল, কমপক্ষে সমস্ত Rails.paths["app/models"].existentডিরেক্টরি গ্লোব করুন । ইচ্ছুক পুরো অ্যাপ্লিকেশনটি লোড করা আরও সম্পূর্ণ উত্তর এবং এটি নিশ্চিত করবে যে মডেলগুলি সংজ্ঞায়িত করার মতো কোনও জায়গা নেই।
sj26

2
আমি sj26 এর অর্থ কী পেয়েছি তবে কিছুটা ভুল হতে পারে: বিকাশের পরিবেশে যতদূর আমি জানি ক্যাশে_ক্ল্যাশগুলি বন্ধ (মিথ্যা) এজন্য আপনাকে সমস্ত মডেল অ্যাক্সেস করতে ম্যানুয়ালি অ্যাপ্লিকেশনটি লোড করতে হবে। এখানে ব্যাখ্যা করা হয়েছে
ম্যাসিগোও

3
@ আজেদি 32 আবার সম্পূর্ণ উত্তর নয়। আপনি যদি কেবলমাত্র মডেলগুলি আগ্রহী করতে চান তবে চেষ্টা করুন: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তালিকাভুক্ত করার আগে তাদের "স্পর্শ" করতে হবে।
এনএফএম

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
কেবলমাত্র মডেলগুলি নয় এটি কিছু টেবিলের সাথে সর্বদা সম্পর্কিত মডেল রাখে না কেন এটি আপনাকে সমস্ত টেবিলগুলি পাবে।
আদালত 21

এই উত্তরটি ভুল হিসাবে বিবেচনা করা উচিত কারণ এটি সারণীর নামটি মডেলটির বহুগুণিত নাম বাদে অন্য কিছু হতে পারে তা কনফিগার করতে (এবং উত্তরাধিকার সূত্রে সাধারণ)। ডিফল্ট কনফিগারেশন থেকে সেটআপটি বিচ্যুত হওয়ার পরেও এই উত্তরটি সঠিক উত্তর দেয়।
lorefnon

কিছু ক্ষেত্রে এটি এর চেয়ে ভাল কাজ করে ActiveRecord::Base.send :subclasses- সারণীর নামগুলি অনুসন্ধান করা ভাল ধারণা। মডেল নামগুলি স্বয়ংক্রিয়ভাবে উত্পন্ন করা লোরেফন উল্লিখিত হিসাবে সমস্যা হতে পারে।
টিলো

.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
আমি এটি গ্রহণ করি যে এর জন্য প্রয়োজনীয় যে ক্লাসগুলি ইতিমধ্যে লোড হয়েছে এবং অটোলয়েড সক্ষম হওয়া সহ বিকাশের পরিবেশে অসম্পূর্ণ ফলাফল দেবে। আমি ডাউনভোট করব না তবে সম্ভবত উত্তরে এটি উল্লেখ করা উচিত।
lorefnon

যথেষ্ট ভাড়া, আপডেট করা
নিমির

আমি কারাগারে 6.0.2 এবং উত্সাহী লোড! বংশধরদের একটি খালি অ্যারে ব্যতীত আর কিছু ফেরত দেওয়ার পদ্ধতি তৈরি করেনি।
jgomo3

23

আপনার কাছে টেবিল-কম মডেল না থাকলে @ হ্নোভিকের সমাধানটি দুর্দান্ত is এই সমাধানটি পাশাপাশি উন্নয়ন মোডেও কাজ করবে

আমার পন্থা যদিও সম্পূর্ণ ভিন্ন -

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

শ্রেণিবদ্ধকরণ আপনাকে স্ট্রিং থেকে ক্লাসের নামটি সঠিকভাবে দেবে বলে মনে করা হচ্ছে । সেফ_ কনটেনটিজ নিশ্চিত করে যে আপনি কোনও ব্যাতিক্রম ছাড়াই নিরাপদে শ্রেণিতে পরিণত করতে পারবেন। আপনার যদি ডাটাবেস টেবিলগুলি মডেল নয় তবে ক্ষেত্রে এটি প্রয়োজন। সংক্ষিপ্ত করুন যাতে অঙ্কের যে কোনও শূন্যস্থান সরানো হয়।


3
এটি অদ্ভুত @ আদিত্য সংঘী আমি সম্পর্কে জানতাম না safe_constantize
লাইটার্স

২.৩.x রেলপথের জন্য, ব্যবহার করুন: অ্যাক্টিভেকর্ড :: বেসসকনেকশন.টিবেলস.ম্যাপ {| x | x.classify.constantize রেসকিউ নিল c .কম্প্যাক্ট
iheggie

@ আইহেগগি এটি বিদ্যমান পোস্টে সম্পাদনার চেয়ে পৃথক উত্তর হিসাবে পোস্ট করা সাধারণত ভাল।
পোকেচু 22

ধন্যবাদ, আমি দেখেছি যে আপনার সেরা আমাকে #adiya জন্য উপযুক্ত উত্তর
বাজিকর

21

আপনি যদি কেবল শ্রেণীর নাম চান:

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

এটি কেবল রিয়েল কনসোলে চালান, আরও কিছু নয়। শুভকামনা!

সম্পাদনা: @ 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 %>

ধন্যবাদ বাউসেল আমি মূলত এই পদ্ধতির পদ্ধতির সাথে গিয়েছিলাম তবে ভিনসেন্ট উপরে পোস্ট করা সমাধানটি ব্যবহার করে শেষ করেছিলাম কারণ এর অর্থ হ'ল আমাকে ফাইলের নামটিও "মডেলাইজড" করতে হবে না (অর্থাত্ কোনও শব্দকে বড় করে তোলা উচিত না! তাদের আবার)।
মিঃ_আরফ

সাবডিরেক্টরি সঙ্গে...'/app/models/**/*.rb'
artemave


11

এক লাইনে: Dir['app/models/\*.rb'].map {|f| File.basename(f, '.*').camelize.constantize }


7
এটি একটি দুর্দান্ত কারণ, 3 রেলগুলিতে, আপনার মডেলগুলি ডিফল্টরূপে স্বয়ংক্রিয়ভাবে লোড হয় না, সুতরাং উপরের পদ্ধতিগুলির অনেকগুলি সমস্ত সম্ভাব্য মডেলগুলিকে ফিরিয়ে দেয় না। আমার Dir['**/models/**/*.rb'].map {|f| File.basename(f, '.*').camelize.constantize }
অনুগতি

2
@ ওয়াভারডিং এটি বেশ সুন্দর, তবে এটি আমার আরএসপেক মডেল পরীক্ষার নামগুলি সংখ্যায়িত করার চেষ্টা করলে তা ত্রুটি থেকে যায়। ;-)
আজেদি 32

@ ভারদারিং চমৎকার সমাধান কিন্তু আপনার যখন নাম স্পেস মডেল রয়েছে তখন তা ভেঙে যায়
মার্কাস মনসুর

10

ActiveRecord::Base.connection.tables


টেবিলের সমস্ত কলামকে তালিকাবদ্ধ করার জন্য একটি দুর্দান্ত ফলোআপ হ'ল <টেবিল_নাম>। কলাম_নাম। সুতরাং আপনার ব্যবহারকারীর টেবিলের জন্য আপনি ব্যবহারকারীর কলাম_নামগুলি কার্যকর করবেন
মার্ক লক্লেয়ার

কেবলমাত্র মডেলগুলি নয় এটি কিছু টেবিলের সাথে সর্বদা সম্পর্কিত মডেল রাখে না কেন এটি আপনাকে সমস্ত টেবিলগুলি পাবে।
আদালতসমাজ

7

মাত্র একটি লাইনে:

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

2
এটি আমার জন্য সমস্ত মডেল প্রদর্শন করে না। নিশ্চিত কেন। আসলে এটি দু'টি সংক্ষিপ্ত।
আদালতসমাজ

1
আমার জন্য কাজ। 'কিছুটা দেরি করে উত্তর দাও। এটা সময় দিতে.
বোল্ডার_রুবি

2
এটি সম্ভবত Rails.application.eager_load!উন্নয়ন মোডে কার্যকর করার আগে প্রয়োজন needs
denis.peplin

7

আমি এখনও মন্তব্য করতে পারি না, তবে আমার ধারণা sj26 উত্তরটি শীর্ষ উত্তর হওয়া উচিত। কেবল একটি ইঙ্গিত:

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

6

রেল R সহ , জেটিওয়ার্ক ডিফল্ট কোড লোডার হয়ে ওঠে।

আগ্রহী লোড করার জন্য, চেষ্টা করুন:

Zeitwerk::Loader.eager_load_all

তারপর

ApplicationRecord.descendants

5

হ্যাঁ এমন অনেকগুলি উপায় রয়েছে যা আপনি সমস্ত মডেলের নামগুলি সন্ধান করতে পারেন তবে আমি আমার রত্ন মডেল_ইনফোতে যা করেছি তা এটি রত্নগুলিতে অন্তর্ভুক্ত সমস্ত মডেল আপনাকে দেবে give

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 এর জন্য কাজ করে R

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

আপেলগুলি এই রেইলগুলির জন্য। অ্যাপ্লিকেশন.ইজার_লোড! ধারণা
সমতুল্য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 নিক্ষেপ করে: কনসোলের স্ট্রিং-এ প্রতীকটির কোনও নিখুঁত রূপান্তর নয়।
স্নোঞ্জেল

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

এটি এই থ্রেডের উত্তরের সেরা অংশ নেয় এবং এটিকে সহজতম এবং সবচেয়ে পুঙ্খানুপুঙ্খ সমাধানে একত্রিত করে। আপনার মডেলগুলি সাব-ডাইরেক্টরিগুলিতে রয়েছে এমন সেটগুলি হ্যান্ডেল করে, সেট_ টেবিল_নাম ব্যবহার করুন ইত্যাদি handle


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 রেলগুলিতে (বাহ godশ্বরের উদ্দেশ্যে তারা দুটি বা দুটি জিনিস বদলেছিল) আমি নিজের নিজের যুক্ত করার সিদ্ধান্ত নিয়েছি। যেগুলি অ্যাক্টিভেকর্ড :: বেসকোনেকশন নামে পরিচিত এবং টেবিলের নামগুলি টানা কাজ করেছে কিন্তু ফলাফলটি আমি পাইনি কারণ আমি কিছু মডেল (অ্যাপ / মডেলগুলির অভ্যন্তরের ফোল্ডারে) লুকিয়ে রেখেছি যা আমি চাইনি মুছে ফেলা:

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

ধরে নিই যে সমস্ত মডেল অ্যাপ্লিকেশন / মডেলগুলিতে রয়েছে এবং আপনার সার্ভারে আপনার গ্রেপ ও অ্যাডক রয়েছে (বেশিরভাগ ক্ষেত্রেই),

# 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

সম্পাদনা করুন:

এই পদ্ধতির অসুবিধা হ'ল এটি এমন মডেলগুলিকে মিস করে যা অপ্রত্যক্ষভাবে অ্যাক্টিভেকর্ডের (যেমন FictionalBook < Book) থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হয় । সবচেয়ে নিশ্চিত উপায় হ'ল Rails.application.eager_load!; ActiveRecord::Base.descendants.map(&:name)যদিও এটি ধীরে ধীরে ধীরে ধীরে।


0

কেউ যদি এটি দরকারী মনে করে তবে আমি এই উদাহরণটি এখানে ফেলছি। সমাধান এই উত্তরটির উপর ভিত্তি করে https://stackoverflow.com/a/10712838/473040

ধরা যাক আপনি একটি কলাম আছে public_uidযে বহির্বিশ্বের করার জন্য একটি প্রাথমিক আইডি হিসেবে ব্যবহার করা হয় (আপনি findjreasons কেন আপনি যে কাজ করতে চাইবেন পারেন এখানে )

এখন ধরা যাক আপনি বিদ্যমান ক্ষেত্রগুলির মডেলগুলির গোছায় এই ক্ষেত্রটি প্রবর্তন করেছেন এবং এখন আপনি সেট করা সমস্ত রেকর্ডগুলি পুনরায় তৈরি করতে চান। আপনি এই মত করতে পারেন

# 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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.