Datamapper object nil on redirect, refresh always loads fine
-
04-12-2019 - |
Question
I'm developing a Rails app that does some plotting behind the scenes to generate a Comparison between various datasets. What I'm seeing is a sporadic 500 error (ActionView::Template::Error
) on generation of the Comparison object in my DataMapper database. It only happens sometimes on one machine, every time on another machine, and never on one. These errors correlate with the performance of the computer, leading me to believe that DataMapper is doing something weird behind the scenes.
I've given up on chasing down the 'why' and am now just trying to catch the 500 error and force a refresh to prevent the reviewers from seeing the problem. However, everything I've tried hasn't worked. Here's my setup:
comparisons_controller.rb
# This is the action which allows for generation of a new comparison. It uses a fork to spawn a child process which generates the comparison. Notifications will appear when this fails or finishes.
def create
first_set = get_msruns_from_array_of_ids(params[:comparison1].uniq)
second_set = get_msruns_from_array_of_ids(params[:comparison2].uniq)
comp = Comparison.new
comp.msrun_firsts = first_set
comp.msrun_seconds = second_set
comp.first_description = params[:first_description]
comp.second_description = params[:second_description]
comp.save
# This should capture the windows fork and prevent it.
if RbConfig::CONFIG['host_os'] === 'mingw32'
redirect_to :action => "show", :id => comp.id
result = comp.graph
a = Alert.create({ :email => false, :show => true, :description => "DONE WITH COMPARISON #{comp.id}" })
else
fork do
result = comp.graph
a = Alert.create({ :email => false, :show => true, :description => "DONE WITH COMPARISON #{comp.id}" })
end
flash[:notice] = "Comparison started. You will be notified when it completes."
# HERE I've attempted to capture problem
begin
render :action => "show"
rescue
redirect_to :action => "show", :id => comp.id
end
end
This shows up in my production.log file:
ActionView::Template::Error (undefined method `first_description' for nil:NilClass):
1: /- @comparison ||= Comparison.get(params[:id])
2: /%h1= "Comparison ##{@comparison.id}"
3: %p <strong>User Description: </strong>
4: <p> Set#1: #{ @comparison.first_description }
5: <p> Set#2: #{@comparison.second_description }
6: <p> #{link_to "Edit", edit_comparison_path(@comparison)}
7: %ul.categories
app/views/comparisons/show.html.haml:4
This error has been bothering me for weeks, but has not yielded to me. Any ideas on the why or the how to catch the error and force a refresh?
Thanks.
Solution
You shouldn't be loading @comparison
inside your view, that's the responsibility of the controller. You've also commented out the line that actually assigns @comparison
so it's hardly surprising it's evaluating as nil
.
Remember that on create
there is no :id
parameter at all. This might explain why it only works on a redirect when finally you have that information available.
What you probably meant was this:
@comparison = Comparison.new
This will define the variable for use inside your views regardless of the parameters.