У меня есть довольно сложный поиск, который я пытаюсь сделать в направляющих, и я не совсем уверен, как, надеясь кто-то может помочь.
У меня есть две модели, Пользователь и Место.
Пользователь связан для Размещения дважды. Однажды для visited_places и однажды для planned_places. Это - многие многим отношения, но использующий has_many: через. Вот отношения от Пользователя.
has_many :visited_places
has_many :visited, :class_name=>"Place", :through=>:visited_places, :source=>:place
has_many :planned_places
has_many :planned, :class_name=>"Place", :through=>:planned_places, :source=>:place
На месте отношения также определяются. Вот определение там
has_many :visited_users, :class_name=>"User", :through=>:visited_places
has_many :planned_users, :class_name=>"User", :through=>:planned_places
Я пытаюсь записать находку на Месте, которое возвращает все места в базе данных, которые не связаны с Пользователем или через посещаемый или запланированный. Прямо сейчас я выполняю это путем простых запросов всех Мест и затем вычитания посещаемый и запланированный от результатов, но я хочу добавить в разбиении на страницы, и я волнуюсь, что это могло усложнить это. Вот мой текущий код.
all_places = Place.find(:all)
all_places = all_places - user.visited - user.planned
Любой знает, как я могу выполнить это в просто вызове к Place.find. Также это - направляющие 3 приложения поэтому, если какое-либо из активных рекордных улучшений делает это легче, они - опция.
Как насчет чего-то вроде:
unvisited_places = Place.find(:all, :conditions => "id NOT IN(#{visited_places.map(&:place_id)})")
Это общая идея - ее можно сделать более эффективной и удобной в зависимости от ваших конечных потребностей.
Вы не показываете это, но если я правильно понимаю, что модели VisitedPlace
и PlannedPlace
имеют отношения belongs_to :user
, тогда эти таблицы имеют вторичный ключ user_id
, верно?
Поэтому в таком случае я думаю, что наиболее эффективно было бы сделать это в базе данных. В этом случае вы ищете select по таблице join из places
, visited_places
и planned_places
, где users. id
не находится ни в visited_places
, ни в planned_places
в sql:
select * from places where id not in
(
(select place_id from visited_places where user_id = ?)
union
(select place_id from planned_places where user_id=?)
)
Если этот запрос работает, вы можете использовать следующее:
Places.find_by_sql(...the complete sql query ...)
В противном случае я бы не знал, как написать такой запрос, за исключением исключения, в Rails 3.