Rails для двух внешних ключей для одной таблицы в одной таблице
Я новичок в RoR и все еще играю с ассоциациями. Мне нужно иметь две ссылки на конкретную модель в другой модели. Код леса не работает, и я получаю сообщение об ошибке "неинициализированной константы".
Команды генерации:
script/generate scaffold BaseModel name:string
script/generate scaffold NewModel name:string base1:references base2:references
db:migrate
Сгенерированные модели:
class NewModel < ActiveRecord::Base
belongs_to :base1
belongs_to :base2
end
и
class BaseModel < ActiveRecord::Base
has_many :new_models # I added this line
end
Когда я пытаюсь создать new_model в /new_models/new
, я попробовал как ID, так и имя BaseModel, но он не работает. Ошибка, которую я получаю:
uninitialized constant NewModel::Base1
Я предположил, что он сопоставляет имена, поэтому в моем методе create я попытался явно установить экземпляры 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
Есть ли что-нибудь, чего я не вижу?
Ответы
Ответ 1
Большинство магов Rails происходит от соглашения по конфигурации. Назвав вещи в соответствии с рекомендациями, Rails может угадать большинство параметров конфигурации. ActiveRecord:: Ассоциации не являются исключениями.
Первый аргумент любой ассоциации ActiveRecord - это имя, которое будет использоваться в модели. Обычно это название другой модели, что соглашение. По умолчанию имя класса является единственным именем ассоциации в camelcase. Внешним ключом по умолчанию в ассоциации является имя ассоциации с пометкой "_id". Если ваше имя ассоциации не совпадает с именем класса или внешним ключом с помощью этих шаблонов, вам необходимо указать их в качестве параметров.
Это сделает то, что вы хотите:
class NewModel
belongs_to :base1, :class_name => "BaseModel"
belongs_to :base2, :class_name => "BaseModel"
end
Лично я бы дал ассоциациям более описательные имена, которые base1 и base2. Что-то вроде этого:
Таблица рейтингов: id, rater_id, rated_id, рейтинг
class Rating
belongs_to :rater, :class_name => "User"
belongs_to :rated_user, :class_name => "User", :foreign_key => "rated_id"
end
Можно использовать другой пример, но это было выбрано, чтобы выделить, когда необходим параметр внешнего ключа.
Ответ 2
Символ, передаваемый методу belongs_to
, должен быть единственным именем другой модели. Поэтому для вашего примера это будет:
class NewModel < ActiveRecord::Base
belongs_to :base_model
end