2011-02-06 12 views
0

これで、データベースの正規化を開始します。現在、私は1つのモデル "製品"を持っています。この製品には、カテゴリ名と商人名の製品が含まれているデータフィード(XML)を介して約60,000の製品が取り込まれています。私はこれらを3つのモデルに分割したいと思います。製品、カテゴリ、および商人を対象としています。2つのテーブル間のリンクを作成する方法

自然のアイデアは、これらのモデルを作成することですので、各製品は、1つのカテゴリと1人の商人を持っています

CATEGORY_IDを| category_name

merchant_id | merchant_name

モデル間の関連付けには、has_one、belongs_toなどのコードを使用することができますが、私は自動的に新しいProductをカテゴリと商人と自動的に関連付けるように努力しています。

私は本の中で空のデータベースを使い始める例を見たことがありますが、それはかなり簡単です。しかし、私は完全なデータベースとカテゴリ名のリストから始めています。

はここで素晴らしい働いている私の製品の作成文である:(私は、次がところで間違っている知っている!)、カテゴリ行...:

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) 

これは理にかなっていますか?

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_namemerchant_nameと呼ばれていると仮定すると、あなたはCategoryMerchant上の関連付けを設定した、あなたはこのような何かを行うことができ

答えて

1

より良い解決策が必要な場合があります。 CATEGORY_IDに製品テーブル内のカテゴリ値またはカテゴリ名に値を設定します。

は、これは実際に設定しますか?

.find_or_create_by

属性で検索を行い、一致する行を返す、またはそれが存在しない場合を作成します。 `.category = 'を使用して関連付けを作成するとき、Railsは外部キーをカテゴリテーブルの行のIDと一致するように設定します。

だから、もっと直接あなたの質問に答えるために:

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

は、これを行うようなものです:

最後から二番目のステップは、値 category.idへの外部キー category_idを設定
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 

。慣例では、外部キーには_idという接尾辞の付いたモデル名が設定されているため、商品表はcategory_idmerchant_idの両方になるように設定されています。

+0

ありがとう、あなたはすでに私の質問に答えているかもしれませんが、上記のコードサンプルを追加しました。 – Zinc

+0

'Category.find_by_name'を' Category.find_or_create_by_name'に置き換え、 'Merchant'と同じことをやってみると、そのトリックをするべきです。 – zetetic

+0

これは実際には、productsテーブルの:category値をcategory_idに設定するか、値をcategory_nameに設定しますか? – Zinc

関連する問題