Подтвердить что ты не робот

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

Есть ли что-нибудь, чего я не вижу?

4b9b3361

Ответ 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