Почему этот Rails с именем scope возвращает пустые (неинициализированные?) Объекты? - PullRequest
3 голосов
/ 02 апреля 2010

В приложении Rails у меня есть модель Machine, которая содержит следующую именованную область действия:

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]
  }
}

Эта именованная область отлично работает в режиме разработки. В рабочем режиме, однако, он возвращает 2 модели, как и ожидалось, но модели пусты или не инициализированы; то есть фактические объекты возвращаются (не nil), но все поля nil. Например, при проверке возвращаемого значения именованной области в консоли возвращается следующее:

[#<Machine >, #<Machine >]

Но, как вы можете видеть, все поля возвращаемых объектов установлены на nil.

Среды производства и разработки по сути одинаковы. Оба используют базу данных SQLite. Вот оператор SQL, сгенерированный для запроса:

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')

Есть идеи, что не так?

Ответы [ 3 ]

0 голосов
/ 12 апреля 2010

Похоже, что группировка может быть причиной проблемы. Являются ли данные одинаковыми как в разработке, так и в производстве?

0 голосов
/ 16 июня 2011

Хм, я не уверен, что у вас проблема, о которой вы думаете.

[#<Machine >, #<Machine >]

подразумевает, что вы вызвали «inspect» для массива ... но не для каждого из отдельных машинных объектов внутри него. Это может быть глупый вопрос, но вы на самом деле пытались вызвать inspect для отдельных возвращаемых объектов Machine, чтобы действительно увидеть, есть ли в столбцах ноль?

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

Если это действительно приводит к данным с нулевым столбцом. Следующее мое предложение - скопировать сгенерированный SQL-код, перейти в стандартный интерфейс mysql и посмотреть, что вы получите, запустив этот SQL-код ... и затем вставить его в свой вопрос выше, чтобы мы могли увидеть.

0 голосов
/ 05 апреля 2010

Это может быть не связано с тем, что с тобой происходит, но звучит достаточно похоже, так что вот так: ты используешь кеш rails для чего-либо?

Я получил почти те же результаты, что и ты, когдаЯ пытался кэшировать результаты запроса (как описано в railscast # 115 ).

Я отследил проблему до все еще ошибки открытых рельсов , которая делает кешированиеActiveRecords непригоден - вы должны выбрать между неиспользованием кэшированного AR или применением патча и получением утечек памяти.

Кэш работает нормально с объектами, не относящимися к AR, поэтому я в итоге "перевел" то, что мне нужно, в целые числаи массивы, и кэшировали это.

Надеюсь, это поможет!

...