Rails search with OR in ActiveRecord::Relation
After a very long search I'm finally asking this question: How do I do OR condition queries with ActiveRecord::Relation in Rails 3.0? Basically I believe it has to do something with scoping and stuff....
Here is what I have:
class Practice < ActiveRecord::Base
attr_accessible :name
has_and_belongs_to_many :doctors
has_and_belongs_to_many :services
end
class Doctor < ActiveRecord::Base
attr_accessible :first_name, :last_name
has_and_belongs_to_many :practices
has_and_belongs_to_many :services
end
class Service < ActiveRecord::Base
attr_accessible :name, :about
has_and_belongs_to_many :practices
has_and_belongs_to_many :doctors
end
What I want to achieve is a form where I can do a search queries and get back ActiveRecord::Relation object(so I can use it with will_paginate and so on) with list of Practices. The query should find any Practice where @practice.name matches query_string OR where @practice.doctors.first_names matches query_string OR where @practice.doctors.last_names matches query_string OR @practice.services.names matches query_string. In other words - lets say query_string matches name of a Service the I would like to get back list of Practices related to this Service. Or if first_name or last_name of a Doctor matches query_string then I get Practices associated to this Doctor/Doctors. And of course good old match by Practice.name too :D
I realize that my has_and_belongs_to_many associations aren't good here, it's just for demonstration purpose but I would be happy to hear if someone can help with migrations and associations for my case.
Thanks.
P.S. as I s开发者_JS百科aid I use Rails 3.0 and I believe it has to do something about scopes(but I can be wrong of course). Also I've tried MetaWhere but couldn't make it work.... :(
Let's see how this turns out:
class Practice < ActiveRecord::Base
class < self
def by_any_name(param)
joins(:doctors, :services).
where(<<-SQL, :name => param)
doctors.first_name = :name OR
doctors.last_name = :name OR
practices.name = :name OR
services.name = :name
SQL
end
end
end
Scopes are so last-year.
And some left joins fer ya (needs testing!):
joins('LEFT JOIN
(doctors_practices INNER JOIN doctors
ON doctors.id = doctors_practices.doctors_id)
ON doctors_practices.practice_id = practices.id
LEFT JOIN
(practices_services INNER JOIN services
ON services.id = practices_services.service_id)
ON practices_services.practice_id = practices.id')
Sheesh, way past my bedtime.
You can dig into ARel OR --see what I did there :)-- check out the very handy gem squeel, which lets you do exactly what you want with a nice syntax.
https://github.com/ernie/squeel
精彩评论