Включить с условием, но всегда показывать результаты первичной таблицы - PullRequest
0 голосов
/ 09 декабря 2010

У меня есть такая функция:

# get all locations, if the user has discovered them or not
def self.getAll(user)
  self.find(:all, :order => 'min_level asc', :include => 'discovered_locations', 
  :conditions => [ "discovered_locations.user_id = ? OR discovered_locations.id is null", user.id] )
end

self на самом деле является моделью BossLocation.Я хочу получить результирующий набор местоположения босса и обнаруженного местоположения, ЕСЛИ это местоположение было обнаружено моим пользователем.Однако, если он не был обнаружен, мне все еще нужен босс, а не объект в качестве обнаруженного местоположения.С помощью приведенного выше кода, если пользователь ничего не обнаружил, я вообще не получаю боссаций.

РЕДАКТИРОВАТЬ:

Мои ассоциации выглядят так:

Ответы [ 2 ]

0 голосов
/ 09 декабря 2010

Мне кажется, проблема в том, что вы указываете user_id в условиях where, а не в условии объединения. Ваш запрос выдаст вам BossLocation только в том случае, если пользователь его обнаружил или вообще не обнаружил ни один пользователь.

Чтобы запрос базы данных соответствовал вашим потребностям, вы можете изменить включение на следующие объединения:

:joins => "discovered_locations ON discovered_locations.boss_location_id = boss_locations.id
           AND discovered_locations.user_id = '#{user.id}'"

НО, я не думаю, что это сильно помогло бы, так как энергичная загрузка Rails не будет работать при использовании таких объединений вместо include.

Если бы я где-то делал что-то подобное, я бы, наверное, разделил это. Возможно, добавив ассоциации для пользователя, как это:

class User < ActiveRecord::Base
  has_many :disovered_locations
  has_many :discovered_boss_locations, :through => :discovered_locations

Обновление:

Таким образом, в вашем контроллере вы можете получить все BossLocations и все обнаруженные BossLocations, например:

@locations = BossLocation.all
@discovered = current_user.discovered_locations.all.group_by(&:boss_location_id)

Чтобы использовать их, когда вы проходите через них, сделайте что-то вроде этого:

<% @locations.each do |location| %>
  <h1><%= location.name %></h1>
  <% unless @discovered[location.id].nil? %>
    <p>Discovered at <%= @discovered[location.id].first.created_at %></p>
  <% end %>
<% end %>

Что он делает, это группирует все обнаруженные местоположения в хеш, где ключом является boss_location_id. Поэтому, когда вы просматриваете все boss_locations, вы просто видите, есть ли в обнаруженном хэше запись, соответствующая boss_id.

0 голосов
/ 09 декабря 2010

"результирующий набор местоположения босса и обнаруженного местоположения, ЕСЛИ это местоположение было обнаружено моим пользователем. Это не левое внешнее соединение. Вы получите все боссаки в любое время. Итак, ваши условия неверны! Это получитbosslocation, что оно обнаружено_locations.user_id = user.id ИЛИ обнаружено_locations.id равно нулю. "1001 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...