ruby on rails - How to create links between two tables -
ok i'm starting on normalising database. have 1 model "products" populated 60,000 products via data feed (xml), contains product category name , merchant name. want split these 3 models; products, categories , merchants.
each product has 1 category , 1 merchant natural idea create these models:
category_id | category_name
merchant_id | merchant_name
i can work out code associate between models i.e. has_one, belongs_to etc i'm struggling work out automatically associate new product category , merchant programatically.
i've seen examples in books start empty database , seems pretty straightforward. however, i'm starting off full database , list of category names.
here product creation statement working great:
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)
would need this, see :category line, (i know following wrong 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)
any ideas? make sense!?
assuming columns called category_name
, merchant_name
, , you've set associations on category
, merchant
, this:
product.all |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
it take while, large datasets might need better solution.
so set :category value in products table category_id or set value category_name?
.find_or_create_by
find on attribute , returns matching row, or creates 1 if not exist. when creating association via `.category=, rails set foreign key match id of row in categories table.
so answer question more directly:
product.create(:category=>category.find_or_create_by_name("magic beans"))
is doing this:
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
where penultimate step sets foreign key category_id
value category.id
. convention associations set such foreign key model name suffixed _id
, products table should have both category_id
, merchant_id
.
Comments
Post a Comment