Postback issue

Hello, I am attempting to implement the “Clean Up Controllers with
Postback Actions” Rails Recipe and I am having a problem with it.

First, the code:

== Controller Method ==

def add_product_type
puts “Params: ‘#{params[:id]}’”
puts “PT: #{@product_type.id}” unless @product_type.nil?
@product_type = ProductType.find_by_id(params[:id]) ||
ProductType.new
puts “PRODUCT TYPE: ‘#{@product_type.name}’ -
‘#{@product_type.id}’”
if request.post?
@product_type.attributes = params[:product_type]
begin
if @product_type.save!
@product_type = nil
redirect_to :action => :index and return
end
@product_type = nil
rescue ActiveRecord::RecordInvalid => e
end
end
end

== View ==

<%= start_form_tag :action => ‘add_product_type’ %>

Name: <%= text_field 'product_type', 'name' %>

<% if @product_type.id.nil? %> <%= submit_tag "Add" %> <% else %> <%= submit_tag "Edit" %> <% end %>

<%= end_form_tag %>

So, I can submit a new type and it works flawlessly. If I immediately
return to the add a product page, it fills in the last product type’s
name. The output from the above puts’s:

Params: ‘’
PRODUCT TYPE: ‘’ - ‘’
127.0.0.1 - - [19/Sep/2006:18:22:39 EDT] “POST /admin/add_product_type
HTTP/1.1” 302 93
http://localhost:3000/admin/add_product_type → /admin/add_product_type
127.0.0.1 - - [19/Sep/2006:18:22:39 EDT] “GET /admin HTTP/1.1” 200 4569
http://localhost:3000/admin/add_product_type → /admin
Params: ‘’
PRODUCT TYPE: ‘gg’ - ‘16’
<--------------------------------------------- ???
127.0.0.1 - - [19/Sep/2006:18:22:42 EDT] “GET /admin/add_product_type
HTTP/1.1” 200 1053
http://localhost:3000/admin → /admin/add_product_type

The params are nil and yet it is finding a product type? Am I doing
something incorrectly here?

I am running the latest rails out of trunk as of today and have the
issue when using webrick, lighttpd and mongrel.

Thanks in advance for any help. I’m not certain where to begin with
this one.

I tested it this morning in ./script/console:

pt = ProductType.find( :first )
=> #<ProductType:0x253b410 @attributes={“name”=>“Poster”, “id”=>“1”}>

ProductType.find_by_id( nil )
=> nil

p = ProductType.new
=> #<ProductType:0x2535150 @attributes={“name”=>nil}, @new_record=true>

p.name = “Yahar”
=> “Yahar”

p.save!
=> true

ProductType.find_by_id( nil )
=> #<ProductType:0x25230f4 @attributes={“name”=>“Yahar”, “id”=>“5”}>

So evidently if you find_by_id( nil ), it returns the last object
created? That sort of breaks the recipe in that it populates the form
when you immediately return to the page.

Essentially, I take it that I have to explicitly check for the
existence of params[:id] which muddies the code a bit.

Hi,

On Wed, 2006-20-09 at 06:22 -0700, [email protected] wrote:

I tested it this morning in ./script/console:

So evidently if you find_by_id( nil ), it returns the last object
created? That sort of breaks the recipe in that it populates the form
when you immediately return to the page.

Essentially, I take it that I have to explicitly check for the
existence of params[:id] which muddies the code a bit.

I’m guessing that you’re using MySQL? Try this in MySQL itself:

    CREATE TABLE foo (id INT(11) NOT NULL AUTO_INCREMENT,
                             name VARCHAR(255),
                             PRIMARY KEY(id));

    INSERT INTO foo (name) VALUES("Tada");
    SELECT * FROM foo WHERE id IS NULL;
    SELECT * FROM foo WHERE id IS NULL;

The first SELECT will return the record you just inserted. The second
select returns the empty set, as should be expected.

Seems to be a problem on tables that have an AUTO_INCREMENT field. It
doesn’t seem to matter whether the table is MyISAM or InnoDB. I
recently got bit by this when two users created their accounts nearly
simultaneously and the second one got the first ones profile.

Not nice.

This does not happen in Postgres, btw.

Rick T.

Wow. I suppose I can test for empty params[:id] first, but that both
makes the code a bit longer and more importantly means I am writing
code to compensate for a specific database implementation.

Did you solve the problem similarly?

Hi,

On Wed, 2006-20-09 at 12:44 -0400, Michael C. wrote:

Transactions don’t help this?

Nope, transactions do not seem to help either. It’s not a good thing
since the identical query twice in a row, with no other changes to the
DB, yield different results.

Transactions don’t help this?

On 9/20/06, Rick T. [email protected] wrote:

    SELECT * FROM foo WHERE id IS NULL;

Not nice.

This does not happen in Postgres, btw.

Rick T.


No matter how far down the wrong road you’ve gone, turn back. – Turkish
proverb

Is this expected behavior (a ‘feature’)?

Hi,

On Wed, 2006-20-09 at 10:00 -0700, [email protected] wrote:

Wow. I suppose I can test for empty params[:id] first, but that both
makes the code a bit longer and more importantly means I am writing
code to compensate for a specific database implementation.

Did you solve the problem similarly?

In the case where I first ran across the issue, yes. In new projects,
I’m just using Postgres instead.

Rick

Hmm, I have used postgres in the past but I recall its clustering
capabilities at the time seemed rather limiting. I’ll have a look
again.

Anyway, thanks a lot for clarifying this for me. I really appreciate
it.

Best regards.