RoR / Squeel - 如何使用Squeel :: Nodes :: Join / Predicates?

时间:2014-12-30 14:45:33

标签: ruby-on-rails squeel

我刚刚继承了一个项目,前一个开发人员使用了Squeel。

我过去一天一直在研究Squeel,并且在网上找到了一些关于如何使用它的知识。它的基本用法很简单。

我在网上找不到的东西(ruby-doc.org除外,它没有给我很多),是如何使用Squeel::Nodes::Join和{{1} }。 我唯一能够找到的是它们是表示连接关联/谓词表达式的节点,我已经想到了这一点。我还不知道如何使用它们。

有人可以帮助我,还是指向一个好的教程/指南?

1 个答案:

答案 0 :(得分:0)

我不妨回答这个问题,因为我能够通过试验和错误以及使用ruby-doc作为指导来弄清楚。我在这里说的一切都不是每个人的最终定义。这就是我所知道的,如果其他人因使用Squeel而无法进行动态查询,将来可能会帮助某人。

Squeel ::节点::存根

让我们实际上从Squeel :: Nodes :: Stub开始。这是一个Squeel对象,可以使用符号或字符串,并可以将其转换为表或列的名称。因此,您可以创建新的Squeel::Nodes::Stube.new("value")Squeel::Nodes::Stube.new(:value),并在其他Squeel节点中使用此存根。您将在下面看到它的使用示例。

Squeel ::节点::加入

Squeel :: Nodes :: Join就像你可能怀疑的那样。它本质上是一个变量,你可以传入一个Squeel连接{},然后执行你想要的连接。你给它一个存根(带有一个表名),你也可以给它另一个变量来改变连接的类型(我现在只知道如何将它改为外连接)。你可以这样创建一个:

Squeel::Nodes::Join.new(Squeel::Nodes::Stub.new(:custom_fields), Arel::OuterJoin)

存根用于让Join知道我们想要加入custom_fields表,而Arel :: OuterJoin只是让Join知道我们想要进行外连接。同样,您不必将第二个参数放入Squeel :: Nodes :: Join.new(),我认为它将默认执行内部联接。然后,您可以将其加入模型:

Person.joins{Squeel::Nodes::Join.new(Squeel::Nodes::Stub.new(:custom_fields), Arel::OuterJoin)}

Squeel ::节点::谓词

Squeel :: Nodes :: Predicate在这一点上看起来非常明显。这只是一个比较。你给它一个存根(带有一个列名),一个比较方法(你可以在Squeel's github的Predicates部分找到它们)和一个要比较的值,如下所示:

Squeel::Nodes::Predicate.new(Squeel::Nodes::Stub(:value), :eq, 5)

你甚至可以很容易地将它们中的两个或它们组合在一起。

AND Squeel::Nodes::Predicate.new(Squeel::Nodes::Stub(:value1), :eq, 5) & Squeel::Nodes::Predicate.new(Squeel::Nodes::Stub(:value2), :eq, 10)

Squeel::Nodes::Predicate.new(Squeel::Nodes::Stub(:value1), :eq, 5) | Squeel::Nodes::Predicate.new(Squeel::Nodes::Stub(:value2), :eq, 10)

这些将返回 Squeel :: Nodes :: And 或带有嵌套Squeel :: Nodes :: Predicates的 Squeel :: Nodes :: Or 。 / p>

然后你可以像这样把它们放在一起(当然你可能在变量b中有连接,而变量b中的谓词,因为你是动态地这样做,否则你应该使用常规Squeel而不是Squeel节点):

Person.joins{Squeel::Nodes::Join.new(Squeel::Nodes::Stub.new(:custom_fields), Arel::OuterJoin)}.where{Squeel::Nodes::Predicate.new(Squeel::Nodes::Stub(:value1), :eq, 5) | Squeel::Nodes::Predicate.new(Squeel::Nodes::Stub(:value2), :eq, 10)}

我很遗憾无法弄清楚如何做子查询:(