2013-06-01 20 views
16

Ho una relazione tra 2 modelli nella mia applicazione di rotaie. Mi sono allontanato dallo standard di come implementare la relazione poiché ho utilizzato un altro campo come chiave primaria e la convenzione di denominazione è diversa. In questo modo la relazione sembrava non essere stabilita. Voglio capire perché.Rails appartiene a has_many con una chiave esterna personalizzata

Questa è una versione tagliata verso il basso dei miei modelli:

class Player < ActiveRecord::Base 
    set_primary_key "alias" 
    attr_accessible :alias, :avatar 
    has_many :player_sessions, :foreign_key => "player_alias", :class_name => "PlayerSession" 
end 

class PlayerSession < ActiveRecord::Base 
    attr_accessible :player_alias, :total_score 
    belongs_to :player, :foreign_key => "player_alias", :class_name => "Player" 
end 

Il modello Player ha il campo alias, che è il nome utente nella mia applicazione. Volevo che il nome utente fungesse da chiave primaria poiché è univoco e sarebbe più semplice migrare i dati e mantenere le relazioni.

Originariamente avevo solo il modello PlayerSession con dati già compilati, ma con l'aumento della mia applicazione ho aggiunto il modello Player e semplicemente inserito una riga con lo stesso alias.

In show vista s' il Player Ho il seguente codice:

Player Sessions: 
<% @player.player_sessions do |player_session| %> 
<ul> 
    <li><h4>Highest Score:</h4> <%= player_session.total_score %> </li> 
</ul> 

Quando provo ad accedere alla pagina che semplice non mostra le informazioni.

Altre informazioni Posso aggiungere è che non ho aggiunto alcuna relazione nel database stesso.

Sono ancora nuovo nei binari e continuo a giocarci. Tutte le opinioni che riguardano gli standard di codifica (al di fuori di rispondere alla domanda) sono benvenute.


Aggiornamento Ho implementato il suggerimento di Babur Usenakunov aggiungendo l'opzione primary_key nei modelli:

class Player < ActiveRecord::Base 
    set_primary_key "alias" 
    attr_accessible :alias, :avatar 
    has_many :player_sessions, :primary_key => "alias", :foreign_key => "player_alias", :class_name => "PlayerSession" 
end 

class PlayerSession < ActiveRecord::Base 
    attr_accessible :player_alias, :total_score 
    belongs_to :player, :primary_key => "alias", :foreign_key => "player_alias", :class_name => "Player" 
end 

anche per testare la i dati sono validi ho acquisito la lista PlayerSession manualmente:

Codice implementato nel controller:

@player_sessions = PlayerSession.where("player_alias = ?", params[:id]) 
.210

codice implementato in vista (che emette i dati):

<% @player_sessions.each do |player_session| %> 
<ul> 
    <li><h4>Highest Score:</h4> <%= player_session.total_score %> </li> 
</ul> 
<% end %> 
+1

Non sono sicuro ma forse dovresti passare anche la chiave primaria nelle opzioni. Per esempio. 'has_many: player_sessions,: primary_key => 'alias',: foreign_key => 'player_alias': class_name => 'PlayerSession'' e' belongs_to: player,: primary_key =>' alias ',: foreign_key => "player_alias", : class_name => "Player" ' –

+0

Provato in questo modo ma ancora non funziona – Drahcir

+0

@Drahcir, sono propenso a pensare che il suggerimento di Babur Usenakunov avrebbe dovuto funzionare. Cosa restituisce '@ player.player_sessions' dopo aver provato il loro suggerimento? – Sun

risposta

1

Se la tabella PlayerSession ha una colonna denominata alias allora la vostra chiave esterna dovrebbe anche essere alias, non player_alias. A titolo di consiglio, sarei diffidente nell'usare un alias come chiave straniera: se il tuo giocatore può/decide di cambiare il suo alias, tutti i record di PlayerSession all'interno del tuo database diventeranno non validi e richiederanno un aggiornamento. Utilizzare un parametro immutabile come player_id sarebbe preferibile utilizzare la colonna di alias esistente IMHO.

+0

L'alias è il nome utente del giocatore. Quindi non può essere cambiato. È come decidere di cambiare il tuo indirizzo email e conservare tutte le tue email – Drahcir

12

ho risolto il problema, è stata una questione di aggiungere each nel circuito ho implementato nella vista:

<% @player.player_sessions.each do |player_session| %> 
<ul> 
    <li><h4>Highest Score:</h4> <%= player_session.total_score %> </li> 
</ul>  
<% end %> 

Dopo aver giocato un po 'intorno, mi sono reso conto che non ho bisogno di aggiungere il primary_key opzione in entrambe le viste e ha lasciato l'opzione chiave esterna solo nel modello Player.

class Player < ActiveRecord::Base 
    set_primary_key "alias" 
    attr_accessible :alias, :avatar 
    has_many :player_sessions, :foreign_key => "player_alias", :class_name => "PlayerSession" 
end 

class PlayerSession < ActiveRecord::Base 
    attr_accessible :player_alias, :total_score 
    belongs_to :player, :class_name => "Player" 
end 
+0

Puoi aiutarmi con questo? http://stackoverflow.com/questions/25047920/rails-belongs-to-with-custom-column-name – mariowise

Problemi correlati