#sql #ruby-on-rails #ruby #ruby-on-rails-3 #activerecord
#sql #ruby-on-rails #ruby #ruby-on-rails-3 #activerecord
Вопрос:
После очень долгого поиска я, наконец, задаю этот вопрос: как мне выполнять ИЛИ обусловливать запросы с помощью ActiveRecord ::Relation в Rails 3.0? В принципе, я считаю, что это должно что-то делать с областью видимости и прочим….
Вот что у меня есть:
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
Чего я хочу добиться, так это формы, в которой я могу выполнять поисковые запросы и возвращать объект ActiveRecord::Relation (чтобы я мог использовать его с will_paginate и так далее) со списком практик. Запрос должен найти любую практику, где @practice.name соответствует query_string ИЛИ где @practice.doctors.first_names соответствует query_string ИЛИ где @practice.doctors.last_names соответствует query_string ИЛИ @practice.services.names соответствует query_string. Другими словами, допустим, query_string соответствует имени службы, я хотел бы получить список действий, связанных с этой службой. Или, если first_name или last_name доктора совпадают с query_string, тогда я получаю практики, связанные с этим врачом / врачами. И, конечно, старое доброе совпадение по Practice.name тоже: D
Я понимаю, что мои ассоциации has_and_belongs_to_many здесь не подходят, это просто для демонстрации, но я был бы рад услышать, может ли кто-нибудь помочь с миграциями и ассоциациями для моего случая.
Спасибо.
PS как я уже сказал, я использую Rails 3.0, и я считаю, что он должен что-то делать с областями видимости (но, конечно, я могу ошибаться). Также я пробовал MetaWhere, но не смог заставить его работать …. : (
Комментарии:
1. Я слышал, вы говорили, что хотите это в одном запросе к БД? =P
2. Да, и причина в том, что я мог бы сделать что-то подобное и вернуть, скажем, 3 объекта ActiveRecord ::Relation, но затем, когда я пытаюсь собрать их вместе, они становятся массивом. Как я уже сказал, мне действительно нужно, чтобы он был ActiveRecord::Relation, чтобы я мог использовать его с нумерацией страниц и другими вещами. P.S. не нашел способа создать объект ActiveRecord::Relation из массива.
3. Да
Relation
, они не работают как представления БД, массив — это массив, и он прямо у вас в оперативной памяти. Ознакомьтесь с моим ответом ниже, надеюсь, он сработает или, по крайней мере, даст вам новую идею!4. Squeel — это обновленная форма MetaWhere, которую следует использовать для Rails 3.0
Ответ №1:
Давайте посмотрим, как это получается:
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
Области действия такие прошлогодние.
И некоторые левые присоединяются к вам (требуется тестирование!):
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')
Блин, мне давно пора спать.
Комментарии:
1. Даст ли это что-нибудь обратно, если у меня будет практика без каких-либо связанных врачей или служб? Спасибо.
2. Нет, только внутренние соединения с этим синтаксисом. Вам нужно левое соединение или что-то в этом роде?
3. да, я думаю, мне нужно что-то вроде левого сустава, потому что даже если я не найду подходящего материала в Службах или у врачей, я все равно хочу получить подходящий материал из Практики. Или, если у меня есть совпадения во всех таблицах, тогда мне нужны все: D, поэтому кажется, что мой большой тренировочный стол находится слева, а два других — справа.
4. спасибо за вашу помощь, но я получаю SQLite3::SQLException: нет такого столбца: doctors_practices.practice_id: ВЫБЕРИТЕ «практика».* ИЗ раздела «практика» Ошибка ЛЕВОГО СОЕДИНЕНИЯ (ActiveRecord::StatementInvalid) с вашим левым соединением. Кроме того, я не думаю, что смогу избежать дублирования результатов с помощью этого запроса, нужно ли мне что-то делать с моими миграциями?
5. Вы можете прочитать имена столбцов из миграций ваших
has_and_belongs_to_many
таблиц соединений.
Ответ №2:
Вы можете покопаться в ARel ИЛИ — посмотрите, что я там сделал 🙂 — ознакомьтесь с очень удобным gem squeel, который позволяет вам делать именно то, что вы хотите, с хорошим синтаксисом.