【问题标题】:Why does this Rails named scope return empty (uninitialized?) objects?为什么这个 Rails 命名范围返回空(未初始化?)对象?
【发布时间】:2011-02-03 20:13:38
【问题描述】:

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

有什么想法吗?

【问题讨论】:

  • 不知道,但是在:select:group 你可以只做machines.*,不是吗?
  • 你检查过由此产生的SQL吗?
  • 我有,现在我已经发布了生成的 SQL。

标签: sql ruby-on-rails sqlite activerecord named-scope


【解决方案1】:

这可能与您发生的事情无关,但听起来很相似,所以这里是:您是否使用 rails 缓存来做任何事情?

当我尝试缓存查询结果时,我得到的结果几乎与您相同(如 railscast #115 中所述)。

我将问题追踪到了一个静止的open rails bug,它使缓存的 ActiveRecords 无法使用 - 您必须在不使用缓存的 AR 或应用补丁和内存泄漏之间做出选择。

缓存适用于非 AR 对象,因此我最终将所需的内容“翻译”为整数和数组,并将其缓存。

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    似乎分组可能会导致问题。开发和生产中的数据是否也相同?

    【讨论】:

      【解决方案3】:

      嗯,我不确定您是否遇到了您认为遇到的问题。

      [#<Machine >, #<Machine >]
      

      暗示您在阵列上调用了“检查”......但不是在其中的每个单独的机器对象上。这可能是一个愚蠢的问题,但您是否真的尝试过对返回的各个 Machine 对象调用 inspect 以真正查看它们在列中是否有 nil?

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

      ?

      如果这确实导致零列数据。我的下一个建议是,您复制生成的 SQL 并进入标准 mysql 界面,看看运行该 SQL 时会得到什么……然后将其粘贴到上面的问题中,以便我们查看。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多