2011-12-08 47 views
1

我有一個模型叫桶具有這種實例方法 Bucket#populate_students_academicwise(mentor)如何利用紅寶石特效的動態執行數據庫查詢

def populate_students_academicwise(mentor) 
    student_ids = Mark.find(:all, 
    :joins => self.student_current_klass, 
    :conditions => ["marks.subject_id = ? AND st.klass_id = ? AND marks.klass_id = ? AND u.account_enabled IS TRUE AND sub.active IS TRUE AND k.active IS TRUE", mentor.subject_id, mentor.klass_id, mentor.klass_id], 
    :group => "marks.student_id", 
    :having => ["ROUND(AVG(marks_obtained)/AVG(marks_total)*100) BETWEEN ? AND ?", min_range, max_range]).collect(&:student_id) 

    self.assign_students(student_ids) 
end 

現在,該查詢返回一組學生,其學習成績之間值的範圍

ROUND(AVG(marks_obtained)/AVG(marks_total)*100) BETWEEN ? AND ?) 

我把這種方法從bucket實例類似這樣的bucket.populate_students_academicwise(mentor)

我想否定這個問題,也就是說,返回那些學習成績不在一定範圍內的學生。我所能想到的是創建另一個運行上述查詢的否定方法。所以,我有另一種方法Bucket#negate_populate_students_academicwise(mentor)

def negate_populate_students_academicwise(mentor) 
    Mark.find(:all, 
     :joins => self.student_current_klass, 
     :conditions => ["marks.subject_id = ? AND st.klass_id = ? AND marks.klass_id = ? AND u.account_enabled IS TRUE AND sub.active IS TRUE AND k.active IS TRUE", mentor.subject_id, mentor.klass_id, mentor.klass_id], 
     :group => "marks.student_id", 
     :having => ["ROUND(AVG(marks_obtained)/AVG(marks_total)*100) NOT BETWEEN ? AND ?", min_range, max_range]).collect(&:student_id) 
end 

現在,該查詢返回一組學生的學習成績不是一個範圍值之間ROUND(AVG(marks_obtained)/AVG(marks_total)*100) NOT BETWEEN ? AND ?

我怎麼能說第一種方法Bucket#populate_students_academicwise(mentor)標有否定方法到它bucket.populate_students_academicwise(mentor).negate那會調用一個proc來否定查詢?

回答

1

所以你想基本上都有這兩個功能,仍然有他們乾的方式?

我會說你應該使用默認參數。

bucket.populate_students_academicwise(mentor) # dont negate 
bucket.populate_students_academicwise(mentor,false) # negate 

在你的方法

def populate_students_academicwise(mentor,in_range = true) 
    student_ids = Mark.find(:all, 
        :joins => self.student_current_klass, 
        :conditions => ["marks.subject_id = ? AND st.klass_id = ? AND marks.klass_id = ? AND u.account_enabled IS TRUE AND sub.active IS TRUE AND k.active IS TRUE", mentor.subject_id, mentor.klass_id, mentor.klass_id], 
        :group => "marks.student_id", 
        :having => ["ROUND(AVG(marks_obtained)/AVG(marks_total)*100) #{'NOT' if !in_range} BETWEEN ? AND ?", min_range, max_range]).collect(&:student_id) 
    self.assign_students(student_ids) 
end 

通過查詢操作的那一點點你得到你NOT(或沒有NOT)取決於參數和不需要在這裏擔心PROC。

+0

謝謝。但是,如果有可能有我想要的解決方案。'bucket.populate_students_academicwise(mentor).negate'看起來比這個'bucket.populate_students_academicwise(mentor,false)'更好。不是嗎? – Vineeth

+0

@vineeth。它是否看起來不錯是值得商榷的。 :)理想情況下,您應該分離出找到student_ids和分配學生的關注點。然後你可以建立3個示波器。第一個是基本範圍,第二個是範圍內有子句的最後一個不在範圍內的子句。然後將相關範圍粘貼到基本範圍以獲得您想要的結果。您應該嘗試在ActiveRelation中編寫上述內容(除非您被困在Rails 2上?)。需要幫助解釋我的解決方案? –

+0

我同意。您的解決方案功能正確。但我的問題的目的是找到一種方法來使我的方法調用,看起來像這個'bucket.populate_students_academicwise(導師).negate',這是所有的:) – Vineeth