Hi, I am experimenting with rails 2.1 using the Netbeans IDE.
Recently I have been looking at the behavior of rails when dealing
with two models that share a has_and_belongs_to_many relation.
I created two simple models, ‘Foo’ and ‘Bar’ that share a
has_and_belongs_to_many relation.
(both foo and bar have a name:string and a value:int field and contain
records like:
‘A’, 10
‘B’, 20
‘C’, 30
etc. )
I also created a table ‘foos_bars’ (with :id=>false). After
generating the scaffolding, I updated views/foos/new.html.erb to
include this bit of code:
<% for item in Bar.all %>
<%= check_box_tag ‘foo[bar_ids][]’, item.id, false %> <
%= item.name %>
<% end %>
This seems to work as advertised. In the ‘new’ dialog, if I check
boxes in the form, and then submit the form, the ‘foos_bars’ join
table is updated with new rows representing the
has_and_belongs_to_many relation between foo and bar.
So my next question was: Is rails clever enough to figure out join
tables when one of the models in the relationship has camel-cased
characters? i.e.: What happens if I have two models ‘FooBar’ and
‘Gizmo’ and their corresponding tables that are identical to ‘foo’
and ‘bar’ in all but name.
So I went through all of the same steps I did for ‘Foo’ and ‘Bar’,
except that the models are named ‘FooBar’ and ‘Gizmo’. I created a
similar join table, ‘foo_bars_gizmos’, and I updated views/foo_bar/
new.html.erb with the same bit of code above with the names changed to
reflect the different models.
<% for item in Gizmo.all %>
<%= check_box_tag ‘foo[gizmo_ids][]’, item.id, false
%> <%= item.name %>
<% end %>
So the question is: does the ‘new’ page for FooBar work the same as
the ‘new’ page for Foo?
The answer, in short, appears to be no.
Both initial ‘new’ HTML pages appear to be identical, reflecting only
the changes to the model names.
However in the case of ‘new’ page for FooBar, when I submit the page,
rails skips updating the database and shows the index page.
Here is the segment from the development log for the ‘new’ page for
‘Foo’ (which works as expected)
(display the initial ‘new’ form)
Processing FoosController#new (for 127.0.0.1 at 2008-06-26 10:06:06)
[GET]
Session ID:
BAh7ByIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo
SGFzaHsABjoKQHVzZWR7ADoMY3NyZl9pZCIlMjYyMjgwZmRkMDZmOGQ3YWZk
MmY1NGU3ZWNkYzU2MDQ=–42def924372179a1cf95f2229a39d317180974cb
Parameters: {“controller”=>“foos”, “action”=>“new”}
Foo Columns (0.008680) SHOW FIELDS FROM foos
Bar Load (0.007275) SELECT * FROM bars
Rendering template within layouts/foos
Rendering foos/new
CACHE (0.000000) SELECT * FROM bars
Bar Columns (0.008892) SHOW FIELDS FROM bars
Completed in 0.16275 (6 reqs/sec) | Rendering: 0.08242 (50%) | DB:
0.03339 (20%) | 200 OK [http://localhost/foos/new]
(process the submission)
Processing FoosController#create (for 127.0.0.1 at 2008-06-26
10:06:23) [POST]
Session ID:
BAh7ByIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo
SGFzaHsABjoKQHVzZWR7ADoMY3NyZl9pZCIlMjYyMjgwZmRkMDZmOGQ3YWZk
MmY1NGU3ZWNkYzU2MDQ=–42def924372179a1cf95f2229a39d317180974cb
Parameters:
{“authenticity_token”=>“0e2e28cc2c93625db6925872dfc05190bbc72ac9”,
“foo”=>{“name”=>“L”, “value”=>“75”, “bar_ids”=>[“3”, “4”]},
“commit”=>“Create”, “controller”=>“foos”, “action”=>“create”}
Foo Columns (0.006579) SHOW FIELDS FROM foos
Bar Columns (0.006674) SHOW FIELDS FROM bars
Bar Load (0.004120) SELECT * FROM bars
WHERE (bars
.id
IN
(3,4))
SQL (0.000788) BEGIN
SQL (0.000732) COMMIT
SQL (0.000975) BEGIN
Foo Create (0.000872) INSERT INTO foos
(name
, value
,
created_at
, updated_at
) VALUES(‘L’, 75, ‘2008-06-26 17:06:23’,
‘2008-06-26 17:06:23’)
bars_foos Columns (0.006560) SHOW FIELDS FROM bars_foos
SQL (0.001076) INSERT INTO bars_foos
(foo_id
, bar_id
) VALUES
(9, 3)
bars_foos Columns (0.005846) SHOW FIELDS FROM bars_foos
SQL (0.001320) INSERT INTO bars_foos
(foo_id
, bar_id
) VALUES
(9, 4)
SQL (0.003362) COMMIT
Redirected to http://localhost:3000/foos/9
Completed in 0.17016 (5 reqs/sec) | DB: 0.03890 (22%) | 302 Found
[http://localhost/foos]
(Looks OK, right?)
Here is the segment from the development log for the ‘new’ page for
‘FooBar’
(display the initial ‘new’ form)
Processing FooBarsController#new (for 127.0.0.1 at 2008-06-26
10:38:56) [GET]
Session ID:
BAh7ByIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo
SGFzaHsGOgtub3RpY2UiIkZvbyB3YXMgc3VjY2Vzc2Z1bGx5IGNyZWF0ZWQu
BjoKQHVzZWR7BjsGVDoMY3NyZl9pZCIlMjYyMjgwZmRkMDZmOGQ3YWZkMmY1
NGU3ZWNkYzU2MDQ=–f26c74fc0800da5ae785e40561fbbe88d2357ee3
Parameters: {“controller”=>“foo_bars”, “action”=>“new”}
FooBar Columns (0.008397) SHOW FIELDS FROM foo_bars
Gizmo Load (0.006131) SELECT * FROM gizmos
Rendering template within layouts/foo_bars
Rendering foo_bars/new
Gizmo Columns (0.006696) SHOW FIELDS FROM gizmos
Completed in 0.13910 (7 reqs/sec) | Rendering: 0.06515 (46%) | DB:
0.02122 (15%) | 200 OK [http://localhost/foo_bars/new]
(process the submission)
Processing FooBarsController#index (for 127.0.0.1 at 2008-06-26
10:39:14) [POST]
Session ID:
BAh7ByIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo
SGFzaHsABjoKQHVzZWR7ADoMY3NyZl9pZCIlMjYyMjgwZmRkMDZmOGQ3YWZk
MmY1NGU3ZWNkYzU2MDQ=–42def924372179a1cf95f2229a39d317180974cb
Parameters:
{“authenticity_token”=>“0e2e28cc2c93625db6925872dfc05190bbc72ac9”,
“foo_bar”=>{“name”=>“M”, “value”=>“80”, “gizmo_ids”=>[“1”, “2”]},
“commit”=>“Create”, “controller”=>“foo_bars”, “action”=>“index”}
FooBar Load (0.006378) SELECT * FROM foo_bars
Rendering template within layouts/foo_bars
Rendering foo_bars/index
FooBar Columns (0.006780) SHOW FIELDS FROM foo_bars
Completed in 0.11590 (8 reqs/sec) | Rendering: 0.06975 (60%) | DB:
0.01316 (11%) | 200 OK [http://localhost/foo_bars]
Note, in this last segment, rails has somehow changed the action from
‘create’ to ‘index’.
My questions are: How? and Why?