Как создать ссылки между двумя таблицами - PullRequest
0 голосов
/ 06 февраля 2011

Хорошо, поэтому я начинаю нормализацию своей базы данных. В настоящее время у меня есть одна модель "Продукты", в которую через канал данных (XML) входит около 60 000 продуктов, в которой содержится продукт с названием категории и названием продавца. Я хочу разделить их на 3 модели; товары, категории и продавцы.

Каждый товар имеет одну категорию и одного продавца, поэтому естественной идеей является создание этих моделей:

category_id | category_name

merchant_id | MERCHANT_NAME

Я могу разработать код для связи между моделями, то есть has_one, own_to и т. Д., Но я изо всех сил стараюсь автоматически связать новый продукт с категорией и продавцом в программном режиме.

Я видел примеры в книгах, где вы начинаете с пустой базы данных, и это кажется довольно простым. Однако я начинаю с полной базы данных и списка названий категорий.

Вот мое заявление о создании продукта, которое отлично работает:

Product.create(:name => node.xpath("./text/name/text()").inner_text.downcase, 
                   :description => node.xpath("./text/desc/text()").inner_text,
                   :brand => node.xpath("./brand/text()").inner_text,
                   :merchant => node.xpath("../@name").inner_text,
                   :category => node.xpath("./cat/text()").inner_text.downcase,
                   :price => "£" + node.xpath("./price/btext()").inner_text)

Должен ли я сделать что-то подобное, см. Строку категории: (я знаю, что следующее неправильно, кстати!) ...

Product.create(:name => node.xpath("./text/name/text()").inner_text.downcase, 
                   :description => node.xpath("./text/desc/text()").inner_text,
                   :brand => node.xpath("./brand/text()").inner_text,
                   :merchant => node.xpath("../@name").inner_text,
                   :category => << Category.find_by_name(node.xpath("./cat/text()").inner_text.downcase),
                   :price => "£" + node.xpath("./price/btext()").inner_text)

Есть идеи? Имеет ли это смысл?

1 Ответ

1 голос
/ 06 февраля 2011

Предполагая, что столбцы называются category_name и merchant_name, и вы установили ассоциации на Category и Merchant, вы можете сделать что-то вроде этого:

Product.all do |product|
  product.category = Category.find_or_create_by_category_name(product.category_name)
  product.merchant = Merchant.find_or_create_by_merchant_name(product.merchant_name)
  product.save!
end

Это займет некоторое время, поэтому для больших наборов данных вам может понадобиться лучшее решение.

Так будет ли фактически задано значение: category в таблице продуктов в category_id или в качестве значения category_name?

.find_or_create_by выполняет поиск атрибута и возвращает соответствующую строку или создает ее, если она не существует. При создании ассоциации с помощью `.category =, Rails установит внешний ключ в соответствии с идентификатором строки в таблице категорий.

Итак, чтобы ответить на ваш вопрос более прямо:

Product.create(:category=>Category.find_or_create_by_name("Magic Beans"))

похоже на это:

category = Category.find_by_name("Magic Beans")
if category.nil?
  category = Category.create(:name=>"Magic Beans")
end
product = Product.new
product.category = category
product.save

, где предпоследний шаг устанавливает внешний ключ category_id в значение category.id. По соглашению ассоциации устанавливаются так, что внешний ключ - это название модели с суффиксом _id, поэтому в таблице ваших продуктов должны быть и category_id, и merchant_id.

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...