2012-10-03 15 views
10

मेरे पास एक मूल्यांकन मॉडल है। मूल्यांकन के कई स्कोर हैं। जब भी कोई नया मूल्यांकन बनाया जाता है, तो प्रत्येक उपयोगकर्ता के लिए स्कोर रिकॉर्ड बनाया जाता है जिसके लिए मूल्यांकन की आवश्यकता होती है (वर्तमान विधि के लिए नीचे देखें, मैं इसे करने के लिए उपयोग कर रहा हूं।) इसलिए, उदाहरण के लिए, 40 स्कोर रिकॉर्ड एक बार में बनाए जा सकते हैं। मूल्यांकन स्वामी तब उपयोगकर्ता के स्कोर के साथ प्रत्येक स्कोर रिकॉर्ड अपडेट करता है।रेल 3, कस्टम कच्चे एसक्यूएल सम्मिलन कथन

मैं कच्चे एसक्यूएल का उपयोग करना चाहता हूं क्योंकि प्रत्येक डालने का अपना लेनदेन होता है और धीमा होता है।

मैं एक बड़े पैमाने पर डालने बयान कच्चे एसक्यूएल का उपयोग करते हुए निम्नलिखित कन्वर्ट करने के लिए करना चाहते हैं:

def build_evaluation_score_items 
    self.job.active_employees.each do |employee| 
    employee_score = self.scores.build 
    employee_score.user_id = employee.id 
    employee_score.save 
    end 
end 

यह कैसे किया जा सकता है पर कोई विचार? मैंने क्रिस हेल्ड की कॉफी संचालित साइट से कोड नमूना अनुकूलित करने का प्रयास किया है, लेकिन कोई पासा नहीं है।

मदद करने के इच्छुक किसी भी व्यक्ति के लिए धन्यवाद!

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

मैं वर्तमान पद्धति के लेनदेन में लपेटा जाता है का उल्लेख उपेक्षित।

तो, अनिवार्य रूप से, मैं तो सब कुछ एक बयान (में डाला जाता है कोड ब्लॉक में जोड़ने के लिए कोशिश कर रहा हूँ ** यह कोड SNIPPIT क्रिस Heald कॉफी संचालित साइट है कि विषय पर चर्चा की ओर से है। मैं यह भी सवाल उठता पूछना होगा लेकिन पोस्ट> 3 साल पुरानी है):।

inserts = [] 
TIMES.times do 
    inserts.push "(3.0, '2009-01-23 20:21:13', 2, 1)" 
end 
sql = "INSERT INTO user_node_scores (`score`, `updated_at`, `node_id`, `user_id`)VALUES #{inserts.join(", ")}" 

मैं अपने प्रयास है कि काम नहीं करते में से कुछ से कोड को दिखाने के लिए खुशी होगी ...

धन्यवाद फिर से!

ठीक है, मैं एक साथ कुछ है कि इसके बाद के संस्करण कोड जैसा दिखता है क्या करने के लिए के रूप में में पत्थर है लेकिन मैं ('evaluation_id' भाग के चारों ओर एक एसक्यूएल बयान अमान्य त्रुटि मिलती है। किसी भी विचार?

def build_evaluation_score_items 
    inserts = [] 
    self.job.active_employees.each do |employee| 
    inserts.push "(#{self.id}, #{employee.id}, #{Time.now}, #{Time.now})" 
    end 
    sql = "INSERT INTO scores ('evaluation_id', `user_id`, 'created_at', `updated_at`)VALUES #{inserts.join(", ")}" 
    ActiveRecord::Base.connection.execute(sql) 
end 

किसी भी विचार ? एसक्यूएल ऊपर कोड त्रुटि पैदा

+1

created_at हिस्सा मेरे लिए काम नहीं करता है, क्योंकि यह एक स्ट्रिंग है postgres को पार्स नहीं है पैदा कर रही है:

फिर आप की तरह कुछ लिख सकते हैं। 'ActiveRecord :: स्टेटमेंट इनवालिड: पीजी :: सिंटेक्स त्रुटि: त्रुटि:" 07 " लाइन 4: (1, 1, 100, 2017-02-20 07:00:56 +0000, 2017-02-20 पर या उसके आसपास वाक्यविन्यास त्रुटि 07 ... ' – Gambo

उत्तर

17

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

def build_evaluation_score_items 
    inserts = [] 
    time = Time.now.to_s(:db) 
    self.job.active_employees.each do |employee| 
    inserts.push "(#{self.id}, #{employee.id}, '#{time}')" 
    end 
    sql = "INSERT INTO scores (evaluation_id, user_id, created_at) VALUES #{inserts.join(", ")}" 
    ActiveRecord::Base.connection.execute(sql) 
end 
+0

मैंने आपको इस्तेमाल किया मेरी खुद की जरूरतों के लिए कुछ एक साथ रखने के लिए आर समाधान। मैं कुछ प्रदर्शन परीक्षण कर रहा था, और डीबी को बहुत सारे यादृच्छिक डेटा (लाखों पंक्तियों) * के साथ भरने की आवश्यकता थी * (यानी ActiveRecord का उपयोग नहीं कर रहा है)। – user664833

+1

यह मेरे लिए काम नहीं करता है क्योंकि 'टाइम' में गलत आउटपुट होता है। पोस्टग्रेस इसे फेंक रहा है: 'ActiveRecord :: स्टेटमेंट इनवालिड: पीजी :: सिंटेक्स त्रुटि: त्रुटि: "07" लाइन 4: (1, 1, 100, 2017-02-20 07:04:11, 2017- 02-20 07:04:11 ... ' – Gambo

+0

कैश साफ़ करने के लिए सम्मिलित करें का प्रयोग करें। – MRifat

5

मुझे लगता है कि आप के लिए देख रहे हैं:

def build_evaluation_score_items 
    ActiveRecord::Base.transaction do 
    self.job.active_employees.each do |employee| 
     employee_score = self.scores.build 
     employee_score.user_id = employee.id 
     employee_score.save 
    end 
    end 
end 

सभी बच्चे लेनदेन स्वचालित रूप से माता पिता ट्रॅन अप करने के लिए "धक्का दे दिया" कर रहे हैं saction। यह इतने सारे लेनदेन के ओवरहेड को रोक देगा और प्रदर्शन में वृद्धि करनी चाहिए।

आप ActiveRecord लेनदेन here के बारे में अधिक पढ़ सकते हैं।

अद्यतन

क्षमा करें, मैं गलत समझा। वंश के लिए उपर्युक्त उत्तर रखते हुए। इस प्रयास करें:

def build_evaluation_score_items 
    raw_sql = "INSERT INTO your_table ('user_id', 'something_else') VALUES " 
    insert_values = "('%s', '%s')," 
    self.job.active_employees.each do |employee| 
    raw_sql += insert_values % employee.id, "something else" 
    end 
    ActiveRecord::Base.connection.execute raw_sql 
end 
+0

सुझाव के लिए धन्यवाद। मैंने अपनी पोस्ट में इंगित करने के लिए उपेक्षित किया कि वर्तमान में कोड में लेनदेन में लपेटा गया बयान है लेकिन यह अभी भी उप-इष्टतम है, क्योंकि यह अभी भी प्रत्येक कर्मचारी के लिए सम्मिलित बयान निष्पादित करता है। लेनदेन के लिए एकमात्र लाभ यह है कि डीबी इंडेक्स अपडेट नहीं किया गया है। –

+0

मैंने अपने उत्तर को एक संभावित समाधान के साथ अपडेट किया है। अगर यह आपकी मदद करता है तो कृपया मुझे बताएं। –

+0

हाय चक - मैं पहले आइटम को रखने के साथ सहमत हूं, यही कारण है कि मैंने इसे ऊपर उठाया। लेनदेन विधि अच्छी समझ में आती है। दुर्भाग्य से, मुझे निम्न त्रुटि मिलती है: ActiveRecord :: बेस: क्लास के लिए अपरिभाषित विधि 'execute'। मैं उपयुक्त निष्पादन कमांड के लिए चारों ओर खोदूँगा और रिपोर्ट करूंगा। –

6

एसक्यूएल सीधे निर्माण (और एसक्यूएल इंजेक्शन और अन्य मुद्दों के लिए अपने आप को खोलने) के बजाय, मैं activerecord-import gem की सिफारिश करेंगे। यह अन्य रणनीतियों के बीच बहु-पंक्ति INSERT आदेश जारी कर सकता है।

def build_evaluation_score_items 
    new_scores = job.active_employees.map do |employee| 
    scores.build(:user_id => employee.id) 
    end 
    Score.import new_scores 
end 
संबंधित मुद्दे