【问题标题】:Scope or instance variable范围或实例变量
【发布时间】:2014-10-28 15:15:07
【问题描述】:

从我所读到的,在 Rails 中使用范围更有效,因为您直接查询模型而不是通过控制器到达模型的实例变量(我是这么看的?)

所以我的控制器中有这个查询

@animal_location = User.select(:town).map(&:town).uniq
["Cardiff", "Newport"]

然后是我的模型中的这个范围

scope :uniq_towns, ->() {
 select("town").group("town")
}
#<ActiveRecord::Relation [#<User id: nil, town: "Cardiff">, #<User id: nil, town: "Newport">]>

在我看来,使用@animal_location = User.select(:town).map(&amp;:town).uniq 访问城镇价值我可以像访问一样

<% @animal_location.each do |loc| %>
  <%= loc %>
<% end %>

或者如果我使用范围并使用@animal_location = User.uniq_towns,在我看来我会使用

<% @animal_location.each do |loc| %>
  <%= loc.town %>
<% end %>

我的第一个问题是我的范围在这种情况下会更快吗,其次我的范围是否正确,因为我正在获取 User id: nil 作为哈希的一部分

谢谢

【问题讨论】:

  • 我不认为作用域查询比常规查询更有效。他们只是在需要时需要更少的打字。

标签: ruby-on-rails activerecord ruby-on-rails-4 named-scope


【解决方案1】:

这取决于您的来源所说的“高效”是什么意思。范围旨在保持代码干燥,在“不要重复自己”的意义上,并为 ActiveRecord (AR) 查询实现“提取方法”重构模式。它们易于维护。

为什么要使用它?如果您在多个地方使用相同的查询,请考虑需要在任何地方更改它的情况。您必须查找并替换所有事件。这种方式容易出错,并且会导致版本控制的更多差异,更难跟踪。

将此查询提取到方法中似乎是一个合乎逻辑的解决方案。 类方法? No, maybe you shouldn't,但简单地说范围就是这样。通过使用范围,您将:

  • 在一个地方构建具有特定含义的查询(并在整个应用程序中使用)
  • 非常确定范围的结果是可链接的,因为结果是有效的 AR 关系(您可以在其之上应用范围)
  • 为查询的含义提供一个可读性好的名称,以保持控制器代码的可读性(在视图中使用范围是有效的,但针对 Rails 遵循的 MVC)

你有:

@animal_location = User.select(:town).map(&:town).uniq

首先,我不明白为什么需要mapgroup,这也可以正常工作并使用SQL DISTINCT

@animal_location = User.select(:town).uniq

这看起来足够短,可以阅读。但让我们在这里演示作用域。在您的模型问题中:

scope :uniq_towns, ->() {
 select("town").uniq
}

...所以你可以在你的控制器中写这个:

@animal_location = User.uniq_towns

还有其他方法可以解决这种情况,例如before_filter,但这超出了问题的范围。

【讨论】:

  • 感谢您的深入回答,当然为我清理了范围。
猜你喜欢
  • 2013-10-01
  • 1970-01-01
  • 2014-08-12
  • 1970-01-01
  • 2014-10-16
  • 2012-06-23
  • 2014-04-18
  • 2017-11-22
  • 2015-11-15
相关资源
最近更新 更多