为什么这个 Rails 命名范围返回空(未初始化?)对象?

发布于 2024-08-27 17:05:24 字数 2416 浏览 8 评论 0原文

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

知道出了什么问题吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

末蓝 2024-09-03 17:05:24

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

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

我将此问题追溯到一个仍然开放轨道错误,该错误导致缓存的 ActiveRecords 无法使用- 你必须选择不使用缓存的 AR 或应用补丁并导致内存泄漏。

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

希望这有帮助!

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!

丘比特射中我 2024-09-03 17:05:24

看来分组可能是导致问题的原因。 dev 和 dev 中的数据是否也相同?生产?

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

梦在夏天 2024-09-03 17:05:24

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

[#<Machine >, #<Machine >]

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

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文