2009-12-11 14 views
19

Soy nuevo en RoR y sigo jugando con asociaciones. Necesito tener dos referencias a un modelo en particular en otro modelo. El código scaffolded no funciona y aparece un error de "constante no inicializada".Asociación de rieles para dos claves foráneas para la misma tabla en una tabla

comandos Generación:

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

modelos de creación:

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

y

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

Cuando intento crear un new_model en /new_models/new, me trataron tanto el ID y el nombre del BaseModel pero no funciona. El error que consigo es:

uninitialized constant NewModel::Base1 

Supuse que mapea los nombres, así que en mi método de crear, traté de establecer explícitamente los casos 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 

¿Hay algo que me falta?

Respuesta

31

La mayor parte de magic de Rails viene de la convención sobre la configuración. Al nombrar cosas de acuerdo con las pautas, Rails puede adivinar la mayoría de las opciones de configuración. ActiveRecord :: Las asociaciones no son excepciones.

El primer argumento de cualquier Asociación de ActiveRecord es el nombre que se utilizará dentro del modelo. Este suele ser el nombre de otro modelo, esa es la convención. Por defecto, el nombre de clase es el singular del nombre de asociación en camelcase. La clave externa predeterminada en la asociación es el nombre de la asociación postfija con "_id". Si el nombre de su asociación no coincide con un nombre de clase o una clave externa según estos patrones, deberá proporcionarlos como opciones.

Esto va a hacer lo que quiere:

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

Personalmente me gustaría dar las asociaciones nombres más descriptivos que Base1 y Base2. Algo como esto:

Calificaciones tabla: Identificación, rater_id, rated_id, calificación

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

Un ejemplo diferente podría haber sido utilizado, pero esto fue elegido para poner de relieve cuando la opción de clave externa es necesaria.

0

El símbolo pasado al método belongs_to debe ser el nombre singular del otro modelo. Así, por tu ejemplo, sería:

class NewModel < ActiveRecord::Base 
    belongs_to :base_model 
end 
Cuestiones relacionadas