2015-03-26 7 views
8

Ho imparato i binari e mi sono imbattuto in un problema con le relazioni. Ho l'associazione molti a molti Utente - Torneo, e per qualche motivo non posso accedere a participated_tournaments sulle istanze di Utente, o non posso accedere ai partecipanti nelle istanze di Torneo.Rails, has_many: through, metodo non definito `to_sym` per nil: NilClass

2.0.0-p643 :001 > Tournament.new.participants 
NoMethodError: undefined method `to_sym' for nil:NilClass 
from /home/marcin/.rvm/gems/ruby-2.0.0-p643/gems/activerecord-4.1.8/lib/active_record/reflection.rb:100:in `_reflect_on_association' 
from /home/marcin/.rvm/gems/ruby-2.0.0-p643/gems/activerecord-4.1.8/lib/active_record/reflection.rb:537:in `source_reflection' 

modello User

class User < ActiveRecord::Base 
    has_many :participants_tournaments 
    has_many :participated_tournaments, :through => :participants_tournaments 
end 

modello Torneo

class Tournament < ActiveRecord::Base 
    has_many :participants_tournaments 
    has_many :participants, :through => :participants_tournaments 
end 

modello ParticipantsTournament

class ParticipantsTournament < ActiveRecord::Base 
    belongs_to :tournament 
    belongs_to :user 
end 

migrazione ParticipantsTournament

def change 
    create_table :participants_tournaments, :id => false do |t| 
    t.integer "tournament_id", 
    t.integer "user_id" 
    end 
end 

Ho letto: This topic on SO, also this topic e visto/letto this railscast, ma io non riesco a ottenere finalmente farlo funzionare.

+0

puoi provare 't = Tournament.new' seguito da' t.participants'? – sixty4bit

+0

con has_many: attraverso sono abbastanza sicuro che la tabella di join abbia bisogno di una colonna id per le chiavi primarie, quindi quando crei quella tabella, assicurati di eliminare ': id => false' nella migrazione. – maxhungry

+0

@MaxHung Non è necessario un ID in una tabella di join. Hai solo bisogno di ID per le cose a cui ti unisci. – Austio

risposta

19

Quando chiami lo .new nei tornei non dispone di id, quindi sarà nil. Pertanto non troverà l'utente.

Inoltre, quando si rimappina un modello in un numero in cui in questo modo è necessario indicare al record attivo qual è il modello che sta cercando. Lo fai con l'argomento :source. Ecco come funzionerebbe il torneo.

class Tournament < ActiveRecord::Base 
    has_many :participants_tournaments 
    has_many :participants, :through => :participants_tournaments, :source => :user 
end 
+0

Grazie! Ha molto senso con: l'opzione di origine, ma quando ho cercato su Google in precedenza, non è stato menzionato molto. Grazie mille! – Marcin