3

In a Rails app, I have a model, Machine, that contains the following named scope:

named_scope :needs_updates, lambda {
  { :select => self.column_names.collect{|c| "\"machines\".\"#{c}\""}.join(','),
    :group => self.column_names.collect{|c| "\"machines\".\"#{c}\""}.join(','),
    :joins => 'LEFT JOIN "machine_updates" ON "machine_updates"."machine_id" = "machines"."id"',
    :having => ['"machines"."manual_updates" = ? AND "machines"."in_use" = ? AND (MAX("machine_updates"."date") IS NULL OR MAX("machine_updates"."date") < ?)', true, true, UPDATE_THRESHOLD.days.ago]
  }
}

This named scope works fine in development mode. In production mode, however, it returns the 2 models as expected, but the models are empty or uninitialized; that is, actual objects are returned (not nil), but all the fields are nil. For example, when inspecting the return value of the named scope in the console, the following is returned:

[#<Machine >, #<Machine >]

But, as you can see, all the fields of the objects returned are set to nil.

The production and development environments are essentially the same. Both are using a SQLite database. Here is the SQL statement that is generated for the query:

SELECT
  "machines"."id",
  "machines"."machine_name",
  "machines"."hostname",
  "machines"."mac_address",
  "machines"."ip_address",
  "machines"."hard_drive",
  "machines"."ram",
  "machines"."machine_type",
  "machines"."use",
  "machines"."comments",
  "machines"."in_use",
  "machines"."model",
  "machines"."vendor_id",
  "machines"."operating_system_id",
  "machines"."location",
  "machines"."acquisition_date",
  "machines"."rpi_tag",
  "machines"."processor",
  "machines"."processor_speed",
  "machines"."manual_updates",
  "machines"."serial_number",
  "machines"."owner"
FROM
  "machines"
LEFT JOIN
  "machine_updates" ON "machine_updates"."machine_id" = "machines"."id"
GROUP BY
  "machines"."id",
  "machines"."machine_name",
  "machines"."hostname",
  "machines"."mac_address",
  "machines"."ip_address",
  "machines"."hard_drive",
  "machines"."ram",
  "machines"."machine_type",
  "machines"."use",
  "machines"."comments",
  "machines"."in_use",
  "machines"."model",
  "machines"."vendor_id",
  "machines"."operating_system_id",
  "machines"."location",
  "machines"."acquisition_date",
  "machines"."rpi_tag",
  "machines"."processor",
  "machines"."processor_speed",
  "machines"."manual_updates",
  "machines"."serial_number",
  "machines"."owner"
HAVING
  "machines"."manual_updates" = 't'
  AND "machines"."in_use" = 't'
  AND (MAX("machine_updates"."date") IS NULL
       OR MAX("machine_updates"."date") < '2010-03-26 13:46:28')

Any ideas what's going wrong?

mipadi
  • 398,885
  • 90
  • 523
  • 479

3 Answers3

0

This might not be related to what is happening to you, but it sounds similar enough, so here it goes: are you using the rails cache for anything?

I got nearly the same results as you when I tried to cache the results of a query (as explained on railscast #115).

I tracked down the issue to a still open rails bug that makes cached ActiveRecords unusable - you have to choose between not using cached AR or applying a patch and getting memory leaks.

The cache works ok with non-AR objects, so I ended up "translating" the stuff I needed to integers and arrays, and cached that.

Hope this helps!

kikito
  • 51,734
  • 32
  • 149
  • 189
0

Seems like the grouping may be causing the problem. Is the data also identical in both dev & production?

0

Um, I'm not sure you're having the problem you think you're having.

[#<Machine >, #<Machine >]

implies that you have called "inspect" on the array... but not on each of the individual machine-objects inside it. This may be a silly question, but have you actually tried calling inspect on the individual Machine objects returned to really see if they have nil in the columns?

Machine.needs_updates.each do |m|
  p m.inspect
end

?

If that does in fact result in nil-column data. My next suggestion is that you copy the generated SQL and go into the standard mysql interface and see what you get when you run that SQL... and then paste it into your question above so we can see.

Taryn East
  • 27,486
  • 9
  • 86
  • 108