列出多个人的首选方式是什么?

时间:2016-04-05 11:33:44

标签: ruby-on-rails

哪个更有效(或者更喜欢):用这样的逗号分隔where条件:

previous_rsvps = Rsvp
  .where(user_id: array_of_ids,
    waitlist_position: nil,
    and so on...)

或将它们链接起来:

previous_rsvps = Rsvp
  .where(user_id: array_of_ids)
  .where(waitlist_position: nil)
  and so on...

或者使用这样的SQL AND更好:

query = <<-SQL
  user_id IN (array_of_ids)
  AND waitlist_position IS NULL
  AND so on...
SQL
previous_rsvps = Rsvp.where(query)

我的查询中确实有一些?参数,如果这有任何不同。

5 个答案:

答案 0 :(得分:0)

这更多的是意见和偏好而不是其他任何问题。我更喜欢你的第一个例子中的方法,因为它更简洁,更容易阅读。它们也应该转换为非常相似的SQL,因此在所有情况下效率都应该相同。

但是,有些情况下使用Ruby语法不适用于更复杂的查询,例如非常规表名,跨多个模型加入等等。熟悉第三个例子的语法非常重要。

答案 1 :(得分:0)

让我们尽可能使用ActiveRecord的强大功能并使用第一个或第二个(我可以根据他们给我的可读性互换使用它们)。

就我个人而言,我发现它首先是一个可读性问题,之后是可维护性问题(这就是为什么我不会使用第三个问题,除非确实需要)。

答案 2 :(得分:0)

在我看来,第一个版本更好,以防你想重构代码并传递更多参数或更复杂的查询,比如你需要连接表并查看联合表:

condition = { waitlist_position:nil, user: {email:"some_email"} }
Rsvp.joins(:users).where(condition)

鉴于条件是在其他地方动态生成的。这样你就可以将condition变量放在哪里,只需在其他地方调整标准。

答案 3 :(得分:0)

我建议避免链接到模型外部的调用,并将查询逻辑保留在模型的命名范围方法中。

Rsvp.for_user(user_id)

class Rsvp
  scope :for_user ->(user_id) do
    where(user_id: user_id, waitlist_position: nil)
  end
end

这将为您的实现增加更多灵活性,使其更加干净并避免不必要的代码重复。

这是关于上述想法的非常好的文章:

http://craftingruby.com/posts/2015/06/24/say-no-to_chained-scopes.html

答案 4 :(得分:0)

通常会使用第一个版本。 Class.where(attr1: "lala", attr2: "lelo")