Adventures in Rails Debugging
I had the greatest rails debugging session ever, tonight. And by greatest I mean incredibly frustrating.
I have a controller that updates an amount value for an Item model. In the unit tests, everything works great. In a rendered partial, however, it was showing an old value. First, let's take a look at the controller code:
logger.info ">> BEFORE! @item.amount=#{@item.amount}"
@item.add_bid @session[:user], @params[:bid_amount]
logger.info ">> AFTER! @item.amount=#{@item.amount}"
render_partial('info', @item) if @request.xhr?
logger.info ">> AFTER PARTIAL! @item.amount=#{@item.amount}"
redirect_to :action => :show
Notice the extensive use of logging... Now's the view:
<% RAILS_DEFAULT_LOGGER.info ">> INSIDE VIEW! info.amount=#{info.amount}" %>
<%=info.amount.format%>
Straight forward, right? Well, it turns out it puts the value of @item.amount before the bid is added! Here's the log output:
>> BEFORE! @item.amount=$85.00 USD
SQL (0.000310) BEGIN
SQL STUFF
SQL (0.000271) COMMIT
>> AFTER! @item.amount=$100.00 USD
>> INSIDE VIEW! @item.amount=$100.00 USD
>> AFTER PARTIAL! @item.amount=$100.00 USD
Notice that the value is updated after the item is saved, before the partial, inside the partial, and after it. So why was it printing the old value? Well, "Scott Barron":http://scott.elitists.net/ gave the first hint to the solution: Multiple render calls are ignored. I restructured the code so that the render methods are only called once whether it's an Ajax request or a normal POST. Still no dice.
Then, I put a breakpoint inside the view, and noticed it was getting called twice! The first time was before the update, which is why the old value was showing. I took another look at the controller, and noticed I was calling the show action also. The show action just loads an item using @params[:id], so I was using it in multiple actions, rather than repeating that bit of code. Well, I just recently added another line that renders that same exact partial for ajax requests.
That is why the rendered data was showing old data. By using a call to another action, I was duplicating the call to the partial, and Rails was probably caching it somewhere.
related
- 2010 Jul 13 In-Process Node.js Queues
- 2010 Jul 07 Geek Talk Interview
- 2010 Jun 28 Tee and Child Processes
- 2010 Jun 23 You can let go now
- 2010 May 17 Railsconf: Building APIs
- 2010 May 10 Nori: Node.js Riak wrapper
- 2010 May 10 No, I did not create a mobile phone framework too
- 2010 May 04 Escaping your test suite with your life
- 2010 Apr 05 Will the iPad kill comic books?
- 2010 Apr 05 First day at GitHub

