ActiveRecord - zapytanie z left join

Cześć,

Mam taki schemat:

[code:ruby]class Game < ActiveRecord::Base
has_many :players
end

class Player < ActiveRecord::Base
belongs_to :game
belongs_to :user
end

class User < ActiveRecord::Base
has_many :players
has_many :games, :through => :players
end[/code]
Jak wydobyć rekordy wszystkich gier z zaznaczeniem tych, w których dany użytkownik gra jako gracz?

W czystym SQL napisałbym coś takiego:

select ... from games left join (select * from players where user_id = ?) players on (players.game_id = games.id)
Da się to jakoś ładnie w ruby zapisać?

# games_controller.rb def my @games = ...? end

Hm… tak na szybko:

def my @games = Game.all @player_hash = Hash[current_user.players.collect { |p| [p.game_id, p] }] end

dzięki czemu dla każdej gry mogę sprawdzić szybko gracza po player_hash[game_id]. Ale może da się łatwiej?

participated = current_user.games.to_a rest = Game.all.to_a - participated
Ale to może być nieefektywne. Zależy ile masz tych gier.

[quote=apohllo]participated = current_user.games.to_a rest = Game.all.to_a - participated
Ale to może być nieefektywne. Zależy ile masz tych gier.[/quote]
może lepiej to odejmowanie zrobić jednak po stronie bazy?

user_games = current_user.games.select(:id).map(&:id) games = Game.where(["id NOT IN (?)", user_games])
ewentualnie z użyciem gemu squeel (nowa wersja meta_where)

games = Game.where{id != user_games}

Ten squeel dużo szybszy od ActiveRecord?

Squeel to tylko nakładka na ActiveRecord więc pewnie dużo szybsze nie jest :smiley: Raczej w ogóle, może nawet jest wolniejsze… nie wiem, nie sprawdzałem.

Może pomyliło Ci się z innym ORM-em - Sequel :wink:

O… fajny ten squeel. Jak czytam, to może właśnie tego mi potrzeba. Nie mam środowiska pod ręką, żeby to sprawdzić, ale może coś takiego zadziała?

@games = Game.joins { current_user.players.outer }