Many to many i wyszukiwanie

Mam 3 modele:

class Event < ActiveRecord::Base
  has_many :lineups
  has_many :artists, through: :lineups
end

class Lineup < ActiveRecord::Base
  belongs_to :event
  belongs_to :artist
end

class Artist < ActiveRecord::Base
  has_many :events, through: :lineups
  has_many :lineups
end

Jak znaleźć wszystkie eventy gdzie graja artysci artist1 i artist2 ? (Artist ma atrybut name)

http://guides.rubyonrails.org/active_record_querying.html#joining-tables

Ale to chyba nie jest zwykly join.
Bo mogę zrobić Event.joins(:artists) ale to dostaje dla kazdego artysty jeden rekord.
Czyli np.
Jezeli mam Event1 w ktorym graja Artist1, Artist2, Artist3 i Event2 w ktorym biora udzial Artist2,Artist3 to po joinie mam:

Event1,Artist1
Event1,Artist2
Event1,Artist3
Event2,Artist2
Event2,Artist3

I jak z tego wybrac te eventy w ktorych graja np. Artist2 i Artist3 razem ?

i poczytaj o join i o tym jaki join AR robi by deefault

1 Like

Nic nie stoi na przeszkodzie, zeby zrobic joina jeszcze raz, wtedy bedziesz mial:

  event   first    second
  Event1, Artist1, Artist1
  Event1, Artist1, Artist2
  Event1, Artist1, Artist3
  Event1, Artist2, Artist1
  Event1, Artist2, Artist2
  Event1, Artist2, Artist3
  Event1, Artist3, Artist1
  Event1, Artist3, Artist2
  Event1, Artist3, Artist3
  Event2, Artist2, Artist2
  Event2, Artist2, Artist3
  Event2, Artist3, Artist2
  Event2, Artist3, Artist3

I z tego mozesz wybrac eventy, dla ktorych np. first = Artist2 i second = Artist3.

Ble, chyba mnie to przerasta, juz drugi dzien nad tym glowkuje :(,SO też nie pomaga :(.
Dzięki za diagramy, o join juz przeczytalem, defaultowo jest INNER JOIN.

Teoretycznie zrobilbym to tak, dla takich danych
e1.artists == [a1, a2, a3]
e2.artists == [a2,a3]

Robie tego defaultowego INNER JOINA

EVENT | ARTIST
e1, a1
e1, a2
e1, a3
e2, a2
e2, a3

I teraz chcialbym imprezy powiedzmy z artystami a1 i a2

Event.joins(:artists).where(artists: { name: ['a1', 'a2']}).pluck(:name)
=> ["e1", "e1", "e2", "e2", "e3"]

Czyli teraz wystarczy wybrac te imprezy ktore maja po 2 wyniki - tyle ilu artystow. Tylko znowu teraz to pewnie dojdzie do tego jakies group i having count > ilu_artystow i nie bardzo mi to wychodzi :confused:

Hmm i chyba dziala :):

lineup = ['a1', 'a2']
Event.select("events.id, count(events.id)").joins(:artists).where(artists: { name: lineup}).group("events.id").having("count(events.id) = ?", lineup.length)