如何在两个表之间创建链接

时间:2011-02-06 20:14:28

标签: ruby-on-rails ruby-on-rails-3

好的,我正在开始规范化我的数据库。目前我有一个型号“产品”,通过数据源(XML)填充了大约60,000种产品,其中包含带有类别名称和商家名称的产品。我想将它们分成3个模型;产品,类别和商家。

每个产品都有一个类别和一个商家,所以自然的想法就是创建这些模型:

category_id | CATEGORY_NAME

merchant_id | MERCHANT_NAME

我可以计算出模型之间关联的代码,例如has_one,belongs_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)

我需要做这样的事情,请参阅:类别行,(我知道以下是错误的btw!)...

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 个答案:

答案 0 :(得分:1)

假设这些列名为category_namemerchant_name,并且您已在CategoryMerchant上设置关联,则可以执行以下操作:

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

这需要一段时间,因此对于大型数据集,您可能需要更好的解决方案。

  
    

那么这实际上会将products表中的:category值设置为category_id还是将值设置为category_name?

  

.find_or_create_by查找属性并返回匹配的行,如果不存在则创建一个。通过`.category =创建关联时,Rails将设置外键以匹配类别表中行的id。

所以更直接地回答你的问题:

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_idmerchant_id