Ruby: how to remove items from array A if it's not in array B?

前端 未结 2 1129
离开以前
离开以前 2021-01-23 14:06

I have prepare these two arrays:

list_of_students = Student.where(\'class = ?\', param[:given_class])
list_of_teachers = Teacher.where(...)

2条回答
  •  無奈伤痛
    2021-01-23 14:10

    You can use the IN SQL statement.

    list_of_students = Student.where('class = ? AND teacher_id IN (?)', param[:given_class], list_of_teachers.map(&:id))
    

    If the list_of_teachers is an ActiveRecord::Relation (and not an array), you can also use #pluck(:id) or (from Rails 4) #ids

    Student.where('class = ? AND teacher_id IN (?)', param[:given_class], list_of_teachers.ids)
    

    There are several ways to write the IN statement. Given you already have a where, I joined it to the main where. But you could also write

    Student.where('class = ?', param[:given_class]).where(teacher_id: list_of_teachers)
    

    or

    Student.where(class: param[:given_class], teacher_id: list_of_teachers)
    

    Also note you don't need to assign the list of teachers to a variable.

    Student.where(class: param[:given_class], teacher_id: Teacher.where(...).ids)
    

    Last but not least, if your Teacher query is simple, you may want to use a single query and a JOIN. Assume you want to get all the Teachers with name Rose.

    Student.where(class: param[:given_class], teacher_id: Teacher.where(name: 'Rose').ids)
    

    You can rewrite the same query to

    Student.where(class: param[:given_class]).joins(:teacher).where(teacher: { name: 'Rose' })
    

    or (the final and shorter expression)

    Student.joins(:teacher).where(class: param[:given_class], teacher: { name: 'Rose' })
    

提交回复
热议问题