आप अपने हैश के आधार पर एक SQL क्वेरी बना सकते हैं। सबसे सामान्य दृष्टिकोण कच्चा एसक्यूएल है, जिसे ActiveRecord . द्वारा निष्पादित किया जा सकता है ।
यहां कुछ अवधारणा कोड दिए गए हैं जो आपको सही विचार देंगे:
query_select = "select * from "
query_where = ""
tables = [] # for selecting from all tables
hash.each do |table, values|
table_name = table.constantize.table_name
tables << table_name
values.each do |q|
query_where += " AND " unless query_string.empty?
query_where += "'#{ActiveRecord::Base.connection.quote(table_name)}'."
query_where += "'#{ActiveRecord::Base.connection.quote(q[fieldName)}'"
if q[:operator] == "starts with" # this should be done with an appropriate method
query_where += " LIKE '#{ActiveRecord::Base.connection.quote(q[val)}%'"
end
end
end
query_tables = tables.join(", ")
raw_query = query_select + query_tables + " where " + query_where
result = ActiveRecord::Base.connection.execute(raw_query)
result.to_h # not required, but raw results are probably easier to handle as a hash
यह क्या करता है:
query_selectनिर्दिष्ट करता है कि आपको परिणाम में कौन सी जानकारी चाहिएquery_whereसभी खोज स्थितियों को बनाता है और SQL इंजेक्शन को रोकने के लिए इनपुट से बच निकलता हैquery_tablesउन सभी तालिकाओं की एक सूची है जिन्हें आपको खोजने की आवश्यकता हैtable_name = table.constantize.table_nameआपको SQL table_name देगा जैसा कि मॉडल द्वारा उपयोग किया गया हैraw_queryउपरोक्त भागों से वास्तविक संयुक्त sql क्वेरी हैActiveRecord::Base.connection.execute(raw_query)डेटाबेस पर sql निष्पादित करता है
सुनिश्चित करें कि उपयोगकर्ता द्वारा सबमिट किए गए इनपुट को उद्धरणों में डालें और SQL इंजेक्शन को रोकने के लिए इसे ठीक से छोड़ दें।
आपके उदाहरण के लिए बनाई गई क्वेरी इस तरह दिखेगी:
select * from companies, categories where 'companies'.'name' LIKE 'a%' AND 'companies'.'hq_city' = 'karachi' AND 'categories'.'name' NOT LIKE '%ECommerce%'
संबंधित तालिकाओं में शामिल होने के लिए इस दृष्टिकोण को अतिरिक्त तर्क की आवश्यकता हो सकती है। आपके मामले में, यदि company और category एक जुड़ाव है, आपको query_where . में कुछ इस तरह जोड़ना होगा
"AND 'company'.'category_id' = 'categories'.'id'"
आसान तरीका: आप मॉडल/टेबल के सभी जोड़े के लिए हैश बना सकते हैं जिन्हें पूछताछ की जा सकती है और वहां उचित जॉइन कंडीशन स्टोर कर सकते हैं। मध्यम आकार के प्रोजेक्ट के लिए भी यह हैश बहुत जटिल नहीं होना चाहिए।
कठिन दृष्टिकोण: यह स्वचालित रूप से किया जा सकता है, यदि आपके पास has_many . है , has_one और belongs_to आपके मॉडल में ठीक से परिभाषित किया गया है। आप reflect_on_all_associations<का उपयोग करके मॉडल की संबद्धता प्राप्त कर सकते हैं। /ए> . एक Breath-First-Search लागू करें या Depth-First Search एल्गोरिदम और किसी भी मॉडल से शुरू करें और अपने जेसन इनपुट से अन्य मॉडलों से मेल खाने वाले संघों की खोज करें। नए BFS/DFS रन तब तक शुरू करें जब तक कि json इनपुट से कोई अनविजिटेड मॉडल न बचे। मिली जानकारी से, आप सभी शामिल होने की शर्तें प्राप्त कर सकते हैं और फिर उन्हें where . में एक्सप्रेशन के रूप में जोड़ सकते हैं कच्चे एसक्यूएल दृष्टिकोण का खंड जैसा कि ऊपर बताया गया है। इससे भी अधिक जटिल, लेकिन करने योग्य भी डेटाबेस schema . को पढ़ना होगा और foreign keys . की तलाश में यहां परिभाषित समान दृष्टिकोण का उपयोग करते हुए ।
संघों का उपयोग करना: यदि वे सभी has_many . से संबद्ध हैं / has_one , आप ActiveRecord . के साथ जुड़ने को संभाल सकते हैं joins . का उपयोग करके inject के साथ विधि इस तरह "सबसे महत्वपूर्ण" मॉडल पर:
base_model = "Company".constantize
assocations = [:categories] # and so on
result = assocations.inject(base_model) { |model, assoc| model.joins(assoc) }.where(query_where)
यह क्या करता है:
- यह बेस_मॉडल को पर इनपुट के रूप में पास करता है Enumerable.inject
, जो बार-बार input.send(:joins, :assoc) को कॉल करेगा (मेरे उदाहरण के लिए यह
Company.send(:joins, :categories)करेगा। जो `कंपनी.श्रेणियों
. के बराबर है - संयुक्त जुड़ाव पर, यह जहां शर्तों को निष्पादित करता है (जैसा कि ऊपर वर्णित किया गया है)
अस्वीकरण आपके द्वारा उपयोग किए जाने वाले SQL कार्यान्वयन के आधार पर आपके लिए आवश्यक सटीक सिंटैक्स भिन्न हो सकता है।