如何利用ruby procs动态执行数据库查询

时间:2011-12-08 07:48:26

标签: ruby-on-rails ruby

我有一个名为Bucket的模型,它有这个实例方法 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 个答案:

答案 0 :(得分: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。