【问题标题】:Tire gem: undefined method `detect'轮胎宝石:未定义的方法“检测”
【发布时间】:2025-12-23 11:25:12
【问题描述】:

我在我的 Rails 应用程序中使用了一些持久的轮胎模型。使用 Tire.search ['index1','index2'], :load => true do ... 搜索一直正常,但我现在创建了一个新的索引和模型,尝试将其包含在搜索中并访问其结果时出现以下错误:

undefined method `detect' for #<AuthoredHistory:0x000001013d6a88>

我看到它来自 Tyre::Results::Collection#results,在最后一行:

@response['hits']['hits'].map { |item| records[item['_type']].detect { |record| record.id.to_s == item['_id'].to_s } }

出于某种原因,records[item['_type']] 为我的其他模型返回了一个 Tire::Results::Collection 对象,但是对于新类,它返回一个 AuthoredHistory 对象,这是我的实际模型类。我在 gem 的 github 页面上看到了一些关于这个的东西,但是我没有对 Tire.configuration.wrapper 做任何事情。我在所有索引模型中都包含持久性、搜索和回调模块。

我错过了什么吗?有人可以指出我正确的方向吗? (karmi,我希望你能在这里救我!)

[更新]

现在我到了某个地方...当结果中仅返回来自特定索引的 1 个结果时发生错误。如果一个索引有 2 个或更多结果,它会将其包装在 Tire::Results::Collection 中。现在来寻找破解...

[再次更新]

找到了破解方法!看看下面的答案...

【问题讨论】:

    标签: ruby-on-rails ruby elasticsearch tire


    【解决方案1】:

    我认为您在检测之前缺少地图的花括号。应该是这样的:

    @response['hits']['hits'].map { |item| records[item['_type']] }.detect { |record| record.id.to_s == item['_id'].to_s }
    

    我不太了解代码库,无法确定这一点,但我认为 records[item['_type']] 将返回其中一个 AuthoredHistory 对象,这些对象上没有 detect 方法。

    detect 方法用于 Ruby 中的 Enumerable 集合,这是map 返回的对象(它将返回一个Array)对象。因此,花括号的位置错误。

    【讨论】:

    • 这当然是合理的逻辑......但使用它会导致更多错误。不确定这是否是解决方案,因为相关行包含在 gem 中...?
    【解决方案2】:

    我发现了一个我认为可行的 hack……不是很漂亮,但这就是 hack 的本质。如果特定模型只有一个结果,则记录不会返回Tire::Results::Collection 对象,而只是返回实际模型的对象,在detect 上失败。所以,我必须检查我们是否有一个 Collection,如果没有,只需将它包装在一个数组中。它现在似乎有效,希望以后没有不良影响......

    这是 hack... 这替换了我在问题中发布的有问题的行:

    @response['hits']['hits'].map do |item|
      collection = records[item['_type']].is_a?(Tire::Results::Collection) ?
        records[item['_type']] :
        [records[item['_type']]]
      collection.detect { |record| record.id.to_s == item['_id'].to_s }
    end
    

    还有!我之前做过一个黑客攻击,以解释整个搜索结果何时只返回一个项目。我必须在上面同样有问题的行之前插入这一行:

    return [records[@response['hits']['hits'].first['_type']]] if @response['hits']['hits'].size == 1
    

    【讨论】:

      【解决方案3】:

      这现在应该在提交44eda24 中得到修复。另见问题#725

      【讨论】: