[英]Rails select by number of associated records
I have following models in my rails app: 我的rails应用程序中有以下模型:
class Student < ApplicationRecord
has_many :tickets, dependent: :destroy
has_and_belongs_to_many :articles, dependent: :destroy
class Article < ApplicationRecord
has_and_belongs_to_many :students, dependent: :destroy
class Ticket < ApplicationRecord
belongs_to :student, touch: true
I need to extract all Students who has less than articles and I need to extract all Students who's last ticket title is 'Something'. 我需要提取所有少于文章的学生,并且我需要提取所有最后一个票证标题为“ Something”的学生。
Everything I tried so far takes a lot of time. 到目前为止,我尝试的所有操作都需要花费大量时间。 I tried mapping and looping through all Students. 我尝试过映射和遍历所有学生。 But I guess what I need is a joined request. 但是我想我需要的是一个联合请求。 I am looking for the most efficient way to do it, as database I am working with is quite large. 我正在寻找最有效的方法,因为我正在使用的数据库很大。
You asked "I need to extract all Students who has less than articles"
. 您问"I need to extract all Students who has less than articles"
。 I'll presume you meant "I need to extract all Students who have less than X articles"
. 我假设您是说"I need to extract all Students who have less than X articles"
。 In that case, you want group
and having
https://guides.rubyonrails.org/active_record_querying.html#group . 在这种情况下,您需要group
并having
https://guides.rubyonrails.org/active_record_querying.html#group 。
For example, Article.group(:student_id).having('count(articles.id) > X').pluck(:student_id)
. 例如, Article.group(:student_id).having('count(articles.id) > X').pluck(:student_id)
。
To address your second question, you can use eager loading https://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations to speed up your code. 要解决第二个问题,您可以使用急切加载https://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations来加快代码的速度。
result = students.filter do |student|
students.tickets.last.name == 'Something'
end
go with @MCI's answer for your first question. 对于第一个问题,请使用@MCI的答案。 But a filter/select/find_all or whatever (although I havn't heared about filter method in ruby) through students record takes n queries where n is the number of student records (called an n+1 query). 但是,通过学生记录进行filter / select / find_all或其他任何操作(尽管我还没有听说过ruby中的过滤方法)需要进行n次查询,其中n是学生记录的数量(称为n + 1查询)。
studs = Student.find_by_sql(%{select tmp.id from (
select student_id as id from tickets where name='Something' order by tickets.created_at desc
) tmp group by tmp.id})
Here association is HABTM so below query should work 这里的关联是HABTM,因此下面的查询应该有效
x = 10
Student.joins(:articles).group("articles_students.student_id").having("count(articles.id) < ?",x)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.