Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何查询Ruby数组,就像使用Rails ActiveRecord一样?_Ruby On Rails_Ruby_Activerecord - Fatal编程技术网

Ruby on rails 如何查询Ruby数组,就像使用Rails ActiveRecord一样?

Ruby on rails 如何查询Ruby数组,就像使用Rails ActiveRecord一样?,ruby-on-rails,ruby,activerecord,Ruby On Rails,Ruby,Activerecord,我有一张桌子,我们叫它小部件吧 我做了一些复杂的处理来获得各种类型的小部件。这些最终会在两个不同的变量中结束 为了简单起见,假设我们有 widgetsA = Widget.where("blah blah blah") widgetsB = Widget.where("blah blah blah blah") 我们仍然可以在widgetsA和widgetsB上执行类似.where的ActiveRecord函数 现在,在检索A和B的集合之后,我需要合并它们,然后对它们执行其他ActiveRec

我有一张桌子,我们叫它小部件吧

我做了一些复杂的处理来获得各种类型的小部件。这些最终会在两个不同的变量中结束

为了简单起见,假设我们有

widgetsA = Widget.where("blah blah blah")
widgetsB = Widget.where("blah blah blah blah")
我们仍然可以在
widgetsA
widgetsB
上执行类似.where的ActiveRecord函数

现在,在检索A和B的集合之后,我需要合并它们,然后对它们执行其他ActiveRecord函数

我想做这样的事

widgetsAll = widgetsA | widgetsB
widgetsAll = widgetsAll.order("RANDOM()")
widgetsAll = widgetsAll.where(answers_count: 0).limit(10) + widgetsAll.where("answers_count > 0").limit(10)
这将获取在A&B中找到的所有小部件(union),将它们随机化,然后选择10个有答案的小部件和10个没有答案的小部件

问题是,我无法使用用户
.order
,而widgetsAll不再是ActiveRecord对象,但它是一个数组,因为
widgetsAll=widgetsA | widgetsB
行。我该怎么做呢

A) 合并/相交两个ActiveRecord集,形成一个ActiveRecord集

B) 如何对数组排序并执行“where”样式的查询

两者都能解决问题。我认为B在性能上更好一些,所以我认为这是更好的答案

有什么想法吗

最后,假设小部件表有idnamedescription列。最后,我们需要一个包含所有内容的ActiveRecord或数组(可能是首选)

编辑:(尝试通过SQL联合进行合并…但不起作用)


一种方法是如下所示:

widgetsAllActual = Widget.where(id: widgetsAll)
这将创建一个新的
Widget::ActiveRecord_Relation
集合,其中包含
widgetsA
widgetsB
中的所有元素,并允许进行进一步的活动记录范围界定

参考:

使用gem,您可以:

widgetsAll = Widget.where.any_of(widgetsA, widgetsB)
我看到两种选择:

1) 在SQL中执行并集:您可以在数据库中执行并集,而不是返回数组的
widgetsA | widgetsB
,以便结果仍然是关系对象:

Widget.from("(#{widgetA.to_sql} UNION #{widgetB.to_sql}) AS widgets")
2) 使用普通数组方法。你的例子是:

widgetsAll = widgetsAll.order("RANDOM()")
widgetsAll = widgetsAll.where(answers_count: 0).limit(10) + widgetsAll.where("answers_count > 0").limit(10)
可以这样翻译:

widgetsAll = widgetsAll.shuffle
widgetsAll = widgetsAll.select { |answer| widget.answer_count == 0 }.take(10) + 
             widgetsAll.select { |answer| widget.answers_count > 0).take(10)

阅读更多信息。

我编辑此文件是为了删除相对较慢的
.map(&:id)
-ActiveRecord为您做了正确的事情。@smathy您知道与操作已创建的数组对象相比,这是否会花费很高的成本(因为涉及到额外的查询)?或者不太可能,因为id无论如何都将被索引?@prakash您知道这是否会比操作已经创建的数组对象更昂贵(因为涉及到额外的查询)?或者不太可能,因为id无论如何都会被索引?这不是一个很好的解决方案:它会进行多次查询,并且不允许您执行顺序和使用分页,这是错误的@apreading-您将在
widgetsAllActual
中得到
AR\u关系,因此您显然仍然能够执行
order
或分页或在AR作用域上执行的任何操作。谢谢,这看起来正是我想要的。从性能的角度来看,您认为什么更好?如果我执行1,会不会因为涉及到额外的查询而成本更高?使用数组操作执行2是否更好?或者两者可能是相同的,因为SQL只是已经确定的ActiveRecords上的一个联合?永远不要这样做2。对于1,我会使用OR而不是union,第一个版本会更快,因为它在数据库中执行union,所以它只在至少运行两个union的示例的查询intead上运行。我添加秒版本只是因为你要求它。我不推荐第二个版本,数据库版本很可能总是更快。@apheading:或者与UNION不同。在这种情况下,当您组合两个关系对象时,您需要使用UNION。任意一个选项都可以@chrisP-这里有些人建议不要使用通常比SQL查询快几个数量级的选项(如使用数组方法)。即使是那些关心做两个查询而不是一个查询的人也担心通常需要几分之一毫秒的查询。做对你最有意义的事,它们都是很好的解决方案。
widgetsAll = widgetsAll.shuffle
widgetsAll = widgetsAll.select { |answer| widget.answer_count == 0 }.take(10) + 
             widgetsAll.select { |answer| widget.answers_count > 0).take(10)