这里有三个重要的模型:目标,学生和研讨会。所有这些都与has_and_belongs_to_many相关。
有一个ObjectiveStudent连接模型,其中包括列“ ready”和“ points_all_time”。有一个ObjectiveSeminar联接模型,其中包括“优先级”列。
我需要收集与给定学生和给定研讨会相关的所有目标。
在研讨会中,还需要将其标记为高于零的“优先级”。所以我认为我需要这一行:
obj_sems = ObjectiveSeminar.where(:seminar => given_seminar).where("priority > ?", 0)
最后,它们还必须是学生已经准备好但未达到7分以上的目标。所以我认为我需要这一行:
obj_studs = ObjectiveStudent.where(:user => given_student, :ready => true).where("points_all_time <= ?", 7)
是否有一种方法可以收集其联接表记录同时出现在上述两个查询中的所有目标?请注意,两个列表都不返回目标。他们分别返回objective_seminars和objective_students。我的最终目标是收集符合以上所有条件的目标。
是我走错了路吗?
奖金问题:我也很乐意在给定的研讨会中按目标的优先级对目标进行排序。但是我担心这会增加数据库负载。您对此有何看法?
在此先感谢您的见解。
答案 0 :(得分:2)
要获取Objectives
,您需要从此开始查询。
为了使用AND
条件查询关联的表,您需要使用这些表进行内部联接。
最终,您将需要一个distinct
运算符才能一次提取每个目标。
您需要的扩展版本(我认为)是:
Objective.joins(objective_seminars: :seminar, objective_student: :student).
where(seminars: seminar_search_params, strudents: student_search_params).
where('objective_seminars.priority > 0').
where('objective_students.ready = 1 AND points_all_time <= 7').
order('objective_seminars.priority ASC').
distinct
现在是否要加载数据库,这一切都取决于索引和表的大小。 上面的查询将转换为以下SQL(或类似内容)。
SELECT DISTINCT objectives.* FROM objectives
INNER JOIN objective_students ON objective_students.objective_id = objectives.id
INNER JOIN students ON students.id = objective_students.student_id
INNER JOIN objective_seminars ON objective_seminars.objective_id = objectives.id
INNER JOIN seminars ON seminars.id = objective_seminars.seminar_id
WHERE seminars_query AND
students_query AND
objective_seminars.priority > 0 AND
objective_students.ready = 1 AND points_all_time <= 7 AND
objective_seminars.priority ASC
因此,您需要添加或扩展索引,以便所有5个表查询都可以具有帮助索引的索引。实际的索引实现取决于您,并且取决于您的应用程序的特定条件(读-写负载,表大小,基数等)