1

I have prepare these two arrays:

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

Student belongs_to Teacher and Teacher has_many students.

And now, I'd need to remove from the list_of_students all items (students), where teacher_id is not included in list_of_teachers.

I found some tips and HOWTO's on comparing arrays, but none of that helped to figure out this case.

Thank you in advance

2 Answers 2

7

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' })
Sign up to request clarification or add additional context in comments.

1 Comment

@user984621 just make sure you switch the order of your queries so list_of_teachers is the first one run as obviously Simone is using the result from that in his query
1

You can try something like

a = [1,2,3]
b = [1,4,5]

pry(main)> a.delete_if {|a1| !b.include? a1}
=> [1]

it checks each value in a is in b or not. If not it deletes the value from a and gives you a array finally.

This is an example. You can use this accordingly

3 Comments

the question is about queries
@МалъСкрылевъ, OP says I have prepared these 2 arrays (Well they are Relations) but he is asking how to remove them from the arrays.
I think the question is not speaking about queries, Instead speaking about how to delete from 2nd array so posted my answer accordingly!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.