views:

81

answers:

3

My development environment:

  • Ubuntu 9
  • Ruby 1.9.1/1.8.7 (rvm)
  • Rails 2.3.5
  • Mysql 5.0
  • Apache Passenger

Below is the part of the program flow to represent the issue.

Request comes:

#action
def create
  begin
    @report = Report.new(params[:report])
    ...  
  rescue LocationNotFound => e
    ...
  end
end

Report constructor:

class Report
  attr_accessor :locations

  def initialize(params = {})
    @locations = params[:locations] ? fetch_locations(params[:locations]) : []
  end
  ...
end

fetch_locations:

def fetch_locations(loc_names)
  Rails.logger.debug "LOC_NAMES: " + loc_names.inspect
  ls = Location.find(:all, :conditions => [ # line 57
    "locations.name in (#{loc_names.map{'?'}.join(',')})",
    *loc_names
  ], :include => [:sample_summaries, :samples]) # loc_names will never be empty
  ...
end

Location model:

class Location < ActiveRecord::Base
  has_many :sample_summaries
  has_many :samples, :through => :sample_summaries
  ...
end

Now, the first time (after passenger restart) this runs fine and does the job. Most of the consequent times I get the error:

Mar-11 11:01:00 #15098 DEBUG: LOC_NAMES: ["Moscow, RF", "London, UK"]
Mar-11 11:01:00 #15098 DEBUG:   Location Load (0.0ms)   SELECT * FROM `locations` WHERE (locations.name in ('Moscow, RF','London, UK'))
Mar-11 11:01:00 #15098 DEBUG:   SampleSummary Load (0.0ms)   SELECT `sample_summaries`.* FROM `sample_summaries` WHERE (`sample_summaries`.location_id IN (1,3))
Mar-11 11:01:00 #15098 DEBUG:   SampleSummary Columns (0.0ms)   SHOW FIELDS FROM `sample_summaries`
Mar-11 11:01:00 #15098 FATAL:
NoMethodError (You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.include?):
  app/models/report.rb:57:in `fetch_locations'
  app/models/report.rb:9:in `initialize'
  app/controllers/report_controller.rb:11:in `new'
  app/controllers/report_controller.rb:11:in `create'

Looks quite random to me. Any ideas?

P.S. I also tried to wrap the query in uncached block, but that didn't change anything.

EDIT

Here is what SampleSummary model looks like:

class SampleSummary < ActiveRecord::Base
  has_many :samples
  belongs_to :location
  ... #validations

  default_scope :include => :samples, :order => 'rss_ts desc'
  ...
end

EDIT2

It doesn't fail in console.

A: 

So, if you run this via ./script/console (the relevant part of the controller action) multiple times with the same arguments it randomly fails? Or it consistently fails? It's not clear.

Just randomly, why not try...

ls = Location.find(:all, :conditions => ["locations.name in (?)", loc_names], :include => :sample_summaries => {:samples})

Philip Hallstrom
Good point. Edited question: it doesn't fail in console
artemave
using `:include => {:sample_summaries => :samples}` did not change anything
artemave
A: 

Since the default scope of sample_summaries includes samples, can you try:

def fetch_locations(loc_names)
  ls = Location.find(:all, 
    :conditions => {:locations => {:name => loc_names}, 
    :include => :sample_summaries
  )
end

Also, does it fail if you leave the :include off completely?

Beerlington
Offtopic, does `:conditions => {:locations => {:name => loc_names}` escape loc_names ?
artemave
Good point about stripping out samples from include. Didn't help though
artemave
Leaving :include off completely moves error to another place (where the data - now missing without :include - is supposed to be accessed)
artemave
Yes, anytime you use the hash form of conditions, it will be escaped. On a side note, the fact that it's failing without the :include seems to indicate a bigger issue. :include is used for eager loading, reducing DB query load. The fact that you are getting an error without it does not seem right. You mentioned that it works when you first start the server, but subsequent calls gave you the error. Does this still happen without the include or does that always fail?
Beerlington
It breaks in the same manner (first time ok, others - fail). Thanks for the escaping hint.
artemave
A: 

This is what it is happening:

https://rails.lighthouseapp.com/projects/8994/tickets/1339-arbase-should-not-be-nuking-its-children-just-because-it-lost-interest

The good news is, it only happens in development mode (where config.cache_classes = false). Changing it to true will make it go away (at the cost of not forgetting to restart server after each change).

artemave