2009-12-11 5 views
19

Je suis nouveau à RoR et joue toujours avec les associations. J'ai besoin d'avoir deux références à un modèle particulier dans un autre modèle. Le code échafaudé ne fonctionne pas et j'obtiens une erreur "constante non initialisée".Rails d'association pour deux clés étrangères pour la même table dans une table

commandes de génération:

script/generate scaffold BaseModel name:string 
script/generate scaffold NewModel name:string base1:references base2:references 
db:migrate 

modèles Generated:

class NewModel < ActiveRecord::Base 
    belongs_to :base1 
    belongs_to :base2 
end 

et

class BaseModel < ActiveRecord::Base 
    has_many :new_models # I added this line 
end 

Lorsque je tente de créer un new_model à /new_models/new, j'ai essayé à la fois l'ID et le nom du BaseModel mais cela ne fonctionne pas. L'erreur que je reçois est:

uninitialized constant NewModel::Base1 

Je l'aurez deviné cartes les noms, donc dans ma méthode de création, j'ai essayé de définir explicitement les instances de BaseModel:

@new_model = NewModel.new(params[:new_model]) 
@base1 = BaseModel.find(1) # this exists 
@base2 = BaseModel.find(2) # this exists 
@new_model.base1 = @base1 # This throws the same error as above 

Est-ce que je suis absent?

Répondre

31

La plupart des magiques de Rails proviennent de la convention sur la configuration. En nommant les choses selon les directives, Rails peut deviner la plupart des options de configuration. ActiveRecord :: Associations ne sont pas des exceptions.

Le premier argument de toute association ActiveRecord est le nom qui sera utilisé dans le modèle. C'est généralement le nom d'un autre modèle, c'est la convention. Par défaut, le nom de la classe est le singulier du nom de l'association dans camelcase. La clé étrangère par défaut dans l'association est le nom d'association postfixé avec "_id". Si le nom de votre association ne correspond pas à un nom de classe ou une clé étrangère par ces modèles, vous devrez les fournir en tant qu'options.

Cela va faire ce que vous voulez:

class NewModel 
    belongs_to :base1, :class_name => "BaseModel" 
    belongs_to :base2, :class_name => "BaseModel" 
end 

Personnellement, je donne les associations des noms plus descriptifs que Base1 et Base2. Quelque chose comme ceci:

table Notes: id, rater_id, rated_id, note

class Rating 
    belongs_to :rater, :class_name => "User" 
    belongs_to :rated_user, :class_name => "User", :foreign_key => "rated_id" 
end 

Un autre exemple aurait pu être utilisé, mais il a été choisi pour mettre en évidence lorsque l'option clé étrangère est nécessaire.

0

Le symbole transmis à la méthode belongs_to doit être le nom au singulier de l'autre modèle. Donc, pour votre exemple, il serait:

class NewModel < ActiveRecord::Base 
    belongs_to :base_model 
end 
Questions connexes