Forum: Ruby on Rails Difficulty using correct moldel for the data in DB

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Marcin Marjanski (Guest)
on 2005-12-19 18:32
(Received via mailing list)
Hi everyone,

I've tried posting the same question to the list last Friday but
somehow did not see it being posted..


I've just started with Rails and Ruby. I just started to play one of
those RPG and to get my feet wet I'm writing an app to keep track of
item fusions. So the scoop is that item can be fused with another
items to create a higher level item. The higher level items can be
fused to create even higher level items ... etc.

I'm using MySQL to store the data. Here is how I have setup the
database:

CREATE TABLE `items` (
 `id` INTEGER(11) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) ,
 `cat_id` INTEGER(11),
 `rank` INTEGER ,
 PRIMARY KEY(`id`)
);

CREATE TABLE `cats` (
 `id` INTEGER(11)  NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255),
 PRIMARY KEY(`id`)
);

CREATE TABLE `fusions` (
 `id` INTEGER(11) NOT NULL AUTO_INCREMENT,
 `item1_id` INTEGER(11),
 `item2_id` INTEGER(11) ,
 `product_id` INTEGER(11),
 PRIMARY KEY(`id`)
);

Now... Creating one-to-many relationship for item/category is cake.
How do I set up my model for item and fusion so I can have something
like below in my view?

<% for fusion in @item.fusions %>
 <%= fusion.item1.name %> + <%= fusion.item2.name %>
<% end %>

BTW I've tried

CREATE TABLE `fusions` (
 `item1_id` INTEGER(11),
 `item2_id` INTEGER(11) ,
 `product_id` INTEGER(11),
 PRIMARY KEY(`item1_id`,`item2_id`)
);

to have has_and_belongs_to_many relationship but it did not work. I
think it has to do with join table having only the id's for the items
that are joined.

I've also tried to use info from
http://wiki.rubyonrails.org/rails/pages/HowToUseMa...
but was unsuccessful.

Because I was unable to come up with a good model for item/fusion and
to limit my database usage, I'm resorting to having controller send
fusions and items ordered by id and doing the following in my view.

<% for fusion in @fusions %>
 <% item1 = @Items[fusion.item1_id.to_i - 1]
 <% item2 = @Items[fusion.item2_id.to_i - 1]

 <%= item1.name %> + <%= item2.name %>
<% end %>

Any ideas?

Marcin
Chris H. (Guest)
on 2005-12-19 19:42
(Received via mailing list)
forgive me if i don't understand correctly, but i think habtm is the
answer,
using self-referential joins.

http://wiki.rubyonrails.com/rails/pages/HowToCreat...
down to 2nd half of page "A Slight Alternative")
Marcin Marjanski (Guest)
on 2005-12-22 02:09
(Received via mailing list)
Thanks Chirs,

Unless I'm doing something wrong I getting the following error

Showing app/views/item/show.rhtml where line #32 raised:
undefined method `product' for #<Item:0x39460c8>
Extracted source (around line #32):

29: <% for f in @item.fusions %>
30:   <tr>
31:     <td> <%= h f.id -%> </td>
32:     <td> <%= h f.product_id -%> <%= h f.product.name -%> </td>
33:     <td> <%= h f.item1_id -%> </td>
34:     <td> <%= h f.item2_id -%> </td>
35:   </tr>

My item.rb:

class Item < ActiveRecord::Base
  has_and_belongs_to_many :fusions,
                          :class_name => 'Item',
                          :join_table => 'fusions',
                          :foreign_key => 'product_id',
                          :association_foreign_key => 'id'

end

How do I associate item1_id, item2_id and product_id in the fusions
table to Item?
I don't get the error when I update line 32 of show.rhtml to:

32:     <td> <%= h f.product_id -%> </td>

I've also experimented with creating habtm table with Item_id and
fusion_id and fusions table that only has id, item1_id and item2_id.
I found that using
http://wiki.rubyonrails.com/rails/pages/HowToCreat...
I'm displaying only portions of fusions (only once where fusion_id is
less than max item_id)

Any ideas?
This topic is locked and can not be replied to.