2011-06-13 3 views
5

Ho la seguente serie di modelli:Rails has_many: attraverso con personalizzato foreign_key

class Cardstock < ActiveRecord::Base 
    has_many :color_matches, :primary_key => :hex, :foreign_key => :hex 
    has_many :palette_colors, :through => :color_matches 
end 

class ColorMatch < ActiveRecord::Base 
    belongs_to :palette_color 
    has_many :cardstocks, :foreign_key => :hex, :primary_key => :hex 
end 

class PaletteColor < ActiveRecord::Base 
    has_many :color_matches 
    has_many :cardstocks, :through => :color_matches 
end 

Calling Cardstock.last.palette_colors produce il seguente errore:

ActiveRecord::StatementInvalid: PGError: ERROR: operator does not exist: character varying = integer 
LINE 1: ...".palette_color_id WHERE (("color_matches".hex = 66)) OR... 
                  ^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. 
: SELECT "palette_colors".* FROM "palette_colors" INNER JOIN "color_matches" ON "palette_colors".id = "color_matches".palette_color_id WHERE (("color_matches".hex = 66)) ORDER BY name ASC 

Questo mi dimostra che la query ActiveRecord genera è utilizzare il id del cartoncino (66) dove dovrebbe essere utilizzato l'esagono del cartoncino (bbbbaf). Da qualche parte, ho bisogno di specificare ActiveRecord per utilizzare la colonna hex per unire tra cardstocks e color_matches. ActiveRecord supporta questo?

+0

Questo è Rails 2.3.x, a proposito. –

risposta

2

I tuoi rapporti sono tutti fuori di testa qui.

  • i rapporti tra Cartoncino e ColorMatch dovrebbe essere un rapporto has_and_belongs_to_many su entrambi i lati
  • ovunque ci sia un has_many relationship, è necessario un corrispondente belongs_to rapporto nel corrispondente classe di
+4

Non è del tutto vero. Non c'è assolutamente niente di sbagliato nell'usare 'has_many: through' invece di' has_and_belongs_to_many'; Credo che sia anche il modo preferito in questi giorni. Tuttavia, hai ragione che c'è qualcosa di sbagliato nelle relazioni. – Emily

+0

Grazie, ho bisogno di cambiare la chiamata 'has_many' in ColorMatches a un' belongs_to'. Ma penso che ci sia di più nel problema, perché quella cattiva query è ancora generata. –

1

C'è qualcosa di sbagliato con il in che modo vengono stabiliti i tuoi rapporti. Non capisco bene il tuo caso d'uso specifico qui, quindi non sono sicuro di dove sia il problema. Il modo di pensare a questo è probabilmente come una relazione molti-a-molti. Capire quali sono i due lati di quel molti-a-molti, e qual è il modello di join. Prenderò un esempio partendo dal presupposto che ColorMatch sia il tuo modello di join: è ciò che lega un PaletteColor a un Cartoncino. In tal caso, si vorrà vostri rapporti a guardare qualcosa di simile:

class Cardstock < ActiveRecord::Base 
    has_many :color_matches, :primary_key => :hex, :foreign_key => :hex 
    has_many :palette_colors, :through => :color_matches 
end 

class ColorMatch < ActiveRecord::Base 
    belongs_to :palette_color 
    belongs_to :cardstocks, :foreign_key => :hex, :primary_key => :hex 
end 

class PaletteColor < ActiveRecord::Base 
    has_many :color_matches 
    has_many :cardstocks, :through => :color_matches 
end 

In termini di database, si dovrebbe avere un campo palette_color_id e hex sul tavolo color_matches, e un campo di hex sul cardstocks tavolo.

+0

Esattamente! Tuttavia, dopo aver impostato le mie associazioni in questo modo, ho ancora lo stesso errore. ActiveRecord supporta questo? Oppure ho bisogno di impostare un altro tavolo, solo per gli esagoni, che i "cartoncini" e "color_matches" puntino entrambi con le colonne di interi? –