简体   繁体   English

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

[英]How to make use of ruby procs to dynamically execute a database query

I have a model called Bucket which has this instance method Bucket#populate_students_academicwise(mentor) 我有一个名为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

Now, this query returns a set of students whose academic performance is between a range of values 现在,此查询返回一组学生的学业成绩介于一系列值之间

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

I call this method from a bucket instance like this bucket.populate_students_academicwise(mentor) 我从像这样的bucket实例中调用此方法bucket.populate_students_academicwise(mentor)

I'd like to negate that query, meaning, return the set of students whose academic performance is NOT between a range of values. 我想否定该查询,也就是说,返回一组学习成绩不在一定范围内的学生。 All I can think of is to create another method that runs negative of the above query. 我所能想到的就是创建另一个对上述查询运行否定的方法。 So I have another method Bucket#negate_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

Now, this query returns a set of students whose academic performance is NOT between a range of values ROUND(AVG(marks_obtained)/AVG(marks_total)*100) NOT BETWEEN ? AND ? 现在,此查询返回一组学习成绩ROUND(AVG(marks_obtained)/AVG(marks_total)*100) NOT BETWEEN ? AND ?范围值ROUND(AVG(marks_obtained)/AVG(marks_total)*100) NOT BETWEEN ? AND ?之间的学生ROUND(AVG(marks_obtained)/AVG(marks_total)*100) NOT BETWEEN ? AND ? ROUND(AVG(marks_obtained)/AVG(marks_total)*100) NOT BETWEEN ? AND ?

How can I call the first method Bucket#populate_students_academicwise(mentor) with a negate method appended to it bucket.populate_students_academicwise(mentor).negate that would call a proc to negate the query? 我该如何调用第一个方法Bucket#populate_students_academicwise(mentor)并在其上附加一个否定方法bucket.populate_students_academicwise(mentor).negate ,该方法将调用proc来否定查询?

So you want to basically have both functionalities and still have them in a DRY way? 因此,您想基本上同时具有这两种功能,并且仍然以DRY方式拥有它们?

I would say you should use a default parameter. 我会说您应该使用默认参数。

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

Within you method 你内在的方法

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

With that little bit of query manipulation you get your NOT (or no NOT) depending on the parameter and dont need to worry about proc here. 通过少量的查询操作,您可以根据参数获得NOT(或没有NOT),而无需担心proc。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM