2017-08-16 3 views
0

J'ai un modèle Selection qui a beaucoup Choices et un DefaultChoice. La relation est structurée de cette façon.Obtenir un résultat inattendu de has_one relation

modèles (je pense ici il y a quelque chose de mal)

class Selection < ApplicationRecord 
    has_many :choices, dependent: :delete_all 
    has_one :default_choice, class_name: 'Choice' 
end 

class Choice < ApplicationRecord 
    belongs_to Selection 
end 

Migration

create_table :selections do |t| 
    t.references :default_choice, index: true 
end 
create_table :choices do |t| 
    t.belongs_to :selection 
end 

D'une certaine façon quelque chose ne va pas:

# let's say: 
selection = Selection.find(1) 
selection.choices << Choice.find(1) 
selection.choices << Choice.find(2) 
selection.default_choice = Choice.find(2) 
selection.save! 

# then 
selection.default_choice_id = 2 
# but 
selection.default_choice.id = 1 

Comment venir ?!

selection.default_choice génère cette requête:

Choice Load (0.5ms) SELECT "choices".* FROM "choices" WHERE "choices"."selection_id" = $1 LIMIT $2 [["selection_id", 1], ["LIMIT", 1]] 
+0

Fondamentalement, elle retourne 'selection.default_choice' de toujours le premier choix de' selection.choices'. –

+0

Pouvez-vous poster la requête SQL qui s'exécute quand vous faites 'selection.default_choice' – Pavan

+0

J'ai mis à jour la question en ajoutant la requête SQL –

Répondre

0

Vous utilisez le même modèle Choice pour les relations has_many :choiches et has_one :default_choice. Donc, lorsque vous interrogez has_one :default_choice résultat sont tous de choices tableau et avec has_one vous obtenez seulement un résultat qui est le premier qu'il trouve référencé à l'objet de sélection.


MISE À JOUR

Pour mettre en œuvre par défaut sur has_many vous pouvez faire quelque chose comme ajouter colonne modèle, choix qui sera vrai si c'est le choix par défaut. Ensuite, la relation has_one devrait avoir une portée pour obtenir le seul choix qui est vrai par défaut comme ceci:

has_one :default_choice, -> { where default_choice: true }, class_name: 'Choice' 
+0

Ceci est clair pour moi. Mais comment puis-je définir un 'default_choice' spécifique? –

+0

C'est une toute autre question que vous avez posée. Vous pouvez faire quelque chose comme ajouter une colonne sur Choice qui sera 'true' si c'est un choix par défaut. Alors la relation has_one devrait avoir une portée pour obtenir seulement le choix qui est vrai par défaut comme ceci: 'has_one: default_choice, -> {où default_choice: true}, class_name: 'Choice'' – meshin