Forum: Ruby on Rails Strange Problem With Unwanted, Transient Caching

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.
Andrew S. (Guest)
on 2007-03-07 15:27
(Received via mailing list)
Hello,

I hope somebody can explain to me what's going on here because I'm
baffled!

In a controller's action I want to create a new order for a
customer.  Because I post back to the same action (not RESTful I
know, but that's for another day) I use code like this:

   def edit
     @order = Order.find_by_id(params[:id]) || Order.new
     ...
   end

I noticed that when params[:id] is nil, the finder still retrieves an
order -- the order whose id matches the :customer_id which is in my
params hash.  Weird.

I then noticed that if I ran the finder a second time, it correctly
returned nil.  Weirder.

And I found the same behaviour if I replaced the find_by_id with
find_by_sql using the SQL statement it generated in the log.  A weird
clue?

Putting all this another way, this code generates the output below:

   def edit
     puts "params: #{params.inspect}"
     puts "params[:id].nil?: #{params[:id].nil?}"
     o = Order.find_by_id(id)
     puts "order: #{o.nil? ? 'nil' : o.inspect}"
     o = Order.find_by_id(id)
     puts "order: #{o.nil? ? 'nil' : o.inspect}"

     ...
   end

This prints out:

   params: {"action"=>"edit", "controller"=>"orders",
"customer_id"=>"1375"}
   params[:id].nil?: true
   order: #<Order:0x35f9a5c @attributes={"id"=>"1375",
"customer_id"=>"502", "required_at"=>nil, "created_at"=>"2004-01-22
12:00:00"}>
   order: nil

So my questions are:

- Why does this finder/query pull out an order the first time instead
of nil?
- Why is the order it wrongly pulls out the one whose id matches the
customer_id?
- Why does the query magically work the second time?
- Have I lost the plot? :)

The fact that find_by_sql exhibits the same weird behaviour leads me
to suspect the database (MySQL).  But if that were caching, surely it
would return the same result both times?

Thanks and regards,
Andy S.
Anthony C. (Guest)
on 2007-03-07 16:42
(Received via mailing list)
Andy:

Yeah, that's weird. I haven't seen anything like it. However, I just
want to confirm if you made a typo in your code:

    def edit
      puts "params: #{params.inspect}"
      puts "params[:id].nil?: #{params[:id].nil?}"

      o = Order.find_by_id(id) # SHOULD THIS BE params[:id] ???

      puts "order: #{o.nil? ? 'nil' : o.inspect}"
      o = Order.find_by_id(id)
      puts "order: #{o.nil? ? 'nil' : o.inspect}"

      ...
    end

If id really is nil, then I'm stumped.

-Anthony
Mark Reginald J. (Guest)
on 2007-03-07 17:12
(Received via mailing list)
Andrew S. wrote:

> returned nil.  Weirder.
>
> And I found the same behaviour if I replaced the find_by_id with
> find_by_sql using the SQL statement it generated in the log.  A weird
> clue?

http://www.ruby-forum.com/topic/70940#164187

--
We develop, watch us RoR, in numbers too big to ignore.
Andrew S. (Guest)
on 2007-03-07 17:22
(Received via mailing list)
Hi Anthony,

Yes, that is a typo in my email.  In my code I have this line just
above the first 'o = Order.find...' line:

id = params[:id]

...so that I could check that id really was what I thought it was.  I
lost it as I wrote the email in a copy-paste mishap.

I can't reproduce this in the console but it happens every time via
the browser.  Bizarre.

Thanks for looking into it,
Andy


On 7 Mar 2007, at 14:40, Anthony C. wrote:
> Yeah, that's weird. I haven't seen anything like it. However, I just
> want to confirm if you made a typo in your code:
>
>     def edit
>       puts "params: #{params.inspect}"
>       puts "params[:id].nil?: #{params[:id].nil?}"
>
>       o = Order.find_by_id(id) # SHOULD THIS BE params[:id] ???

Yes!  That's what it was in my actual code (rather than this email).

>
>       puts "order: #{o.nil? ? 'nil' : o.inspect}"
>       o = Order.find_by_id(id)
And this one too:           ^^
Andrew S. (Guest)
on 2007-03-07 17:26
(Received via mailing list)
Mark,

On 7 Mar 2007, at 15:11, Mark Reginald J. wrote:
>>
>> I then noticed that if I ran the finder a second time, it correctly
>> returned nil.  Weirder.
>>
>> And I found the same behaviour if I replaced the find_by_id with
>> find_by_sql using the SQL statement it generated in the log.  A weird
>> clue?
>
> http://www.ruby-forum.com/topic/70940#164187

Thank you -- that's exactly what I was after.

I've spent several hours puzzling over this today so I'm very
grateful for the solution!

Regards,
Andy S.
This topic is locked and can not be replied to.