2012-07-27 18 views
8

मैं रेल की नौसिखिया हूं और रेल के साथ एक टेबल पर एक खोज करने की कोशिश कर रहा हूं, और मैं बस ऐसा करने के लिए अपने एसक्यूएल ज्ञान का उपयोग कर रहा हूं। लेकिन यह सिर्फ रेल या रूबी की तरह नहीं लगता है ...सशर्त जोड़ने के लिए जहां रेलों में खंड

क्या मैं नीचे क्या कर रहा हूं करने का कोई बेहतर तरीका है? (मूल रूप से, केवल तारीख तर्क पारित SQL के अगर वे भर रहे हैं)

def search(begin_date=nil, end_date=nil) 

    subject = " and created_at " 

    if !(begin_date.nil? || end_date.nil?) 
     where_part = subject + "BETWEEN :begin_date AND :end_date" 
    else if (begin_date.nil? && end_date.nil?) 
     where_part = "" 
    else if(begin_date.nil?) 
     where_part = subject + " <= :end_date" 
    else if (end_date.nil?) 
     where_part = subject + " >= :begin_date" 
    end 
    end 
    end 
    end 

    User.joins(places: {containers: {label: :user}}).where("users.id= :user_id "+where_part, user_id: self.id, begin_date:begin_date, end_date:end_date).group(...).select(...) 
end 

संपादित

user.rb

has_many :containers 
has_many :user_places 
has_many :places, through: :user_places 
has_many :labels 

place.rb

has_many :containers 
has_many :user_places 
has_many :users, through: :user_places 

कंटेनर। आरबी

belongs_to :label 
belongs_to :place 
belongs_to :user 

label.rb

belongs_to :user 
has_many :containers 

असल में, मैं स्थान प्रति, किसी दिए गए उपयोगकर्ता के लेबल के भीतर या एक सीधा संबंध के साथ कंटेनरों की संख्या की गिनती मिलता है, और यह फिल्टर करने के लिए सक्षम होना चाहते हैं करना चाहते हैं शुरुआत और समाप्ति तिथियों से।

इनमें से कोई भी तारीख शून्य हो सकती है, और इसलिए मुझे इसे "क्वेरी" में संबोधित करने की आवश्यकता होगी।

मेरा सवाल है: मैं रेलवे तरीके कैसे कर सकता हूं? मैंने http://guides.rubyonrails.org/active_record_querying.html पर एक नज़र डाली और शायद मैं कहीं भी छोड़कर कमांड का उपयोग कर सकता हूं ... लेकिन यह रिलेशनशिप मॉडल सिर्फ ActiveRecord के साथ ऐसा करने के लिए थोड़ा जटिल लगता है ... मैं कैसे कर सकता हूं, मुझे सच में लगता है कि मुझे ActiveRecord का उपयोग करना चाहिए, लेकिन कैसे?

धन्यवाद

+0

[यहाँ कैसे करना है का एक अच्छा उदाहरण है सक्रिय रिकॉर्ड के साथ जुड़ जाता है] [1] [1]: http://stackoverflow.com/questions/764538/ruby-on-rails-how -to-join-two-table –

+0

हाय, मेरी समस्या शामिल होने के साथ नहीं है ... मैंने अभी उन्हें नहीं लिखा क्योंकि वे प्रासंगिक नहीं हैं।मेरी बात सशर्त खोज पैरामीटर – MrWater

+0

@itsalltime के साथ है - मुझे लगता है कि बॉब क्या कहने की कोशिश कर रहा है - क्यों सीधे रिकॉर्ड एसक्यूएल लिखने के बजाय सक्रिय रिकॉर्ड का उपयोग नहीं करते? http://guides.rubyonrails.org/active_record_querying.html – JasCav

उत्तर

18

तो आप अपने आधार क्वेरी निर्माण कर सकते हैं आप एक सवाल के कई where कॉल आवेदन कर सकते हैं:

query = User.joins(...) 
      .group(...) 
      .select(...) 
      .where('users.id = :user_id', :user_id => self.id) 

और फिर अपने दिनांक अंतराल के आधार पर एक और where कॉल जोड़ें:

if(begin_date && end_date) 
    query = query.where(:created_at => begin_date .. end_date) 
    # or where('created_at between :begin_date and :end_date', :begin_date => begin_date, :end_date => end_date) 
elsif(begin_date) 
    query = query.where('created_at >= :begin_date', :begin_date => begin_date) 
elsif(end_date) 
    query = query.where('created_at <= :end_date', :end_date => end_date) 
end 

प्रत्येक where कॉल आपके समग्र WHERE क्लॉज का उपयोग करके एक और टुकड़ा जोड़ता है और ऐसा कुछ करता है:

q = M.where(a).where(b).where(c) 

WHERE a AND b AND c कहने जैसा ही है।

+0

हाय, यह उत्तर बहुत अच्छा है। धन्यवाद। ऐसा लगता है कि मैं start_date का उपयोग नहीं कर सकता .. end_date (और शून्य के बजाए खाली उपयोग करना था), क्योंकि मैं टेक्स्ट फ़ील्ड से डेटाटाइम एकत्र कर रहा हूं और उन्हें स्थानीय रूप से परिवर्तित कर रहा हूं। 'if! start_date.blank? start_date = DateTime.strptime ("# {start_date} 00:00:00", "% m /% d /% वाई% एच:% एम:% एस")। To_datetime अंत 'मैं आपके वैकल्पिक सुझाव का उपयोग कर समाप्त हुआ : 'या कहां (' create_date और: end_date 'के बीच बनाया गया: start_date => start_date,: end_date => end_date) ' – MrWater

+0

@itsalltime:' start_date .. end_date' का उपयोग करना चाहिए अगर' start_date' और 'end_date'' वास्तविक तिथि ऑब्जेक्ट्स लेकिन ऐसा लगता है कि वास्तव में आपके पास तार हैं। मैं उन्हें उपयोग करने से पहले उन्हें डेट ऑब्जेक्ट्स में कनवर्ट करने की अनुशंसा करता हूं ताकि आपको केवल एक ही स्थान पर डेट प्रारूप समस्याओं के बारे में चिंता करनी पड़े। –

+0

हाय, मैं उन्हें उपरोक्त पोस्ट किए गए फ़ंक्शन के साथ परिवर्तित करता हूं, लेकिन यहां तक ​​कि start_date .. end_date काम नहीं करता है, और यही कारण है कि मुझे वैकल्पिक – MrWater

0

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

Link explaining how to join tables with active record

+0

मुझे वास्तव में जुड़ने का उपयोग करने के बारे में कुछ संदेह थे, लेकिन मुझे लगता है कि मुझे अपने संपादित उत्तर में पोस्ट किए जाने के बाद मैं जो चाहता था उसे संबोधित करने का एक तरीका मिला। मेरी बात वास्तव में सशर्त खोज पैरामीटर के साथ है। – MrWater

+0

ओह, इस तरह के सामान और सामान के लिए: http://www.rigelgroupllc.com/blog/2014/09/14/working-with-complex-sql-statements/ – Danny

संबंधित मुद्दे