मेरे पास निम्नलिखित मॉडल और संबंध हैं:

class Company < ApplicationRecord
  has_many :jobs, dependent: :delete_all
  has_many :job_technologies, through: :jobs
end

class Job < ApplicationRecord
  has_many :job_technologies
  has_many :technologies, through: :job_technologies
  belongs_to :company
end

class JobTechnology < ApplicationRecord
  belongs_to :job
  belongs_to :technology
end

नौकरी प्रौद्योगिकियों में यह स्कीमा है:

  create_table "job_technologies", force: :cascade do |t|
    t.bigint "job_id"
    t.bigint "technology_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.integer "title_matches"
    t.integer "description_matches"
    t.index ["job_id"], name: "index_job_technologies_on_job_id"
    t.index ["technology_id"], name: "index_job_technologies_on_technology_id"
  end

तो जब मैं एक JobTechnology बनाता हूं तो मैं इसे इस तरह कर रहा हूं:

JobTechnology.new(
        job: Job.new(title: 'some title'),
        technology: Technology.where(name: 'javascript').first,
        title_matches: 1,
        description_matches: 10
      )

इसका मतलब है कि अगर मैं देखना चाहता हूं कि नौकरी में कौन सी तकनीकें हैं तो मैं कर सकता हूं:

Job.first.job_technologies
=> [#<JobTechnology:0x00007ffc5b5957e0
  id: 647,
  job_id: 263,
  technology_id: 1,
  created_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  updated_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  title_matches: 0,
  description_matches: 2>,
 #<JobTechnology:0x00007ffc5b5953a8
  id: 648,
  job_id: 263,
  technology_id: 4,
  created_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  updated_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  title_matches: 1,
  description_matches: 2>,
 #<JobTechnology:0x00007ffc5b595100

यह हमेशा अद्वितीय तकनीकों की एक सूची होगी क्योंकि मैं प्रत्येक कार्य के लिए प्रत्येक अद्वितीय तकनीक (जैसे 'जावास्क्रिप्ट', 'रूबी', आदि...) के लिए केवल एक JobTechnology बना रहा हूं।

अब मैं देखना चाहता हूं कि कंपनी के पास कौन सी तकनीकें हैं। मैं कर सकता हूँ:

Company.first.job_technologies
=> [#<JobTechnology:0x00007ffc56e3b9d0
  id: 647,
  job_id: 270,
  technology_id: 1,
  created_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  updated_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  title_matches: 0,
  description_matches: 2>,
 #<JobTechnology:0x00007ffc56e3b908
  id: 648,
  job_id: 271,
  technology_id: 1,
  created_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  updated_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  title_matches: 1,
  description_matches: 2>,
 #<JobTechnology:0x00007ffc56e3b818
  id: 649,
  job_id: 263,
  technology_id: 31,
  created_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  updated_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  title_matches: 0,
  description_matches: 1>,
 #<JobTechnology:0x00007ffc56e3b750
  id: 650,
  job_id: 263,
  technology_id: 32,
  created_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  updated_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  title_matches: 0,
  description_matches: 2>]

समस्या यह है कि Company में JobTechnologies हो सकते हैं जो 'डुप्लिकेट' प्रौद्योगिकियां हैं (कल्पना कीजिए कि एक Company में 5 Jobs हैं और उन सभी में JobTechnology 'जावास्क्रिप्ट' है। ) आप ऊपर के उदाहरण में देख सकते हैं कि हमारे पास है

#<JobTechnology:0x00007ffc56e3b9d0
  id: 647,
  job_id: 270,
  technology_id: 1,
  created_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  updated_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  title_matches: 0,
  description_matches: 2>,
 #<JobTechnology:0x00007ffc56e3b908
  id: 648,
  job_id: 271,
  technology_id: 1,
  created_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  updated_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  title_matches: 1,
  description_matches: 2>,

मैं JobTechnology को मर्ज करना चाहता हूं ताकि हमारे पास प्रत्येक तकनीक के लिए केवल एक Technology की गणना हो, लेकिन मैं title_matches और description_matches को जोड़ना चाहता हूं। तो उपरोक्त उदाहरण बन जाएगा

#<JobTechnology:0x00007ffc56e3b9d0
  id: 647,
  job_id: 263,
  technology_id: 1,
  created_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  updated_at: Mon, 31 May 2021 12:56:36 UTC +00:00,
  title_matches: 1,
  description_matches: 4>

मैं इसे Company पर एक विधि के रूप में कर सकता था जो इन्हें मैन्युअल रूप से मर्ज करता है, लेकिन हर बार जब हम इसे खोजते हैं तो मुझे इसे मैन्युअल रूप से करने की आवश्यकता होगी। मैं सोच रहा हूं कि इसे हासिल करने का कोई कम खर्चीला तरीका है या नहीं।

मुझे कैशिंग के बारे में ज्यादा जानकारी नहीं है लेकिन शायद ऐसा करना सबसे अच्छा विकल्प है - इस पर कोई लिंक/विचार/सलाह की सराहना की। मुझे बस एक एहसास है कि सक्रिय रिकॉर्ड क्वेरी के माध्यम से इसे हर बार मैन्युअल रूप से गणना किए बिना ऐसा करने का एक तरीका है।

मेरे पास एक और विचार है कि क्या मुझे एक CompanyTechnology मॉडल बनाना चाहिए और शायद यही वह जगह है जहां यह तर्क रहना चाहिए

0
Robert Faldo 1 जून 2021, 10:29

1 उत्तर

सबसे बढ़िया उत्तर

id, job_id, created_at और updated_at प्राप्त करना, जैसा कि आपने अपने उदाहरण में उल्लिखित किया है, अधिक अर्थ नहीं रखता है। यदि परिणाम 5 JobTechnology-s के माध्यम से एकत्रित किया जाता है, तो यह कौन सी आईडी होनी चाहिए? मुझे लगता है कि आपको इसकी परवाह नहीं है। आइए उन वस्तुओं पर ध्यान केंद्रित करें जिन्हें आपने स्पष्ट रूप से परिभाषित किया है, technology_id, title_matches और description_matches

आप जो खोज रहे हैं उसे SQL में GROUP BY कहा जाता है। रेल में समतुल्य .group() है। हम परिणामों को technology_id और प्रत्येक technology_id कुल (योग) के लिए title_matches और description_matches के आधार पर समूहबद्ध करना चाहते हैं।

Company.first.job_technologies.group(:technology_id).pluck(
  :technology_id, 'sum(title_matches)', 'sum(description_matches)'
)

यह सरणी की एक सरणी लौटाएगा जहां प्रत्येक आंतरिक सरणी में 3 तत्व होते हैं जिन्हें हम ढूंढ रहे हैं।

एसक्यूएल अक्षर से छुटकारा पाने के लिए हम एरेल का उपयोग उसी चीज़ के लिए कर सकते हैं जो केवल सुरक्षित है।

Company.first.job_technologies.group(:technology_id).pluck(
  :technology_id,
  JobTechnology.arel_table[:title_matches].sum,
  JobTechnology.arel_table[:description_matches].sum
)

यदि आप सरणियों की एक सरणी के बजाय एक सक्रिय रिकॉर्ड संबंध प्राप्त करना चाहते हैं, तो pluck के बजाय select का उपयोग करें। हालांकि, इससे सावधान रहें क्योंकि चूंकि इसमें कोई आईडी कॉलम नहीं है, इसलिए यह थोड़ा अजीब काम कर सकता है।

1
Siim Liiser 1 जून 2021, 18:17