Ruby 活动记录中范围内的映射

Ruby 活动记录中范围内的映射,ruby,activerecord,padrino,Ruby,Activerecord,Padrino,我有一个活动记录,其中有一个用例:我想在活动记录范围内使用map。以下是我的代码: class SupportedGeoIdAndLocation < ActiveRecord::Base scope :supported_geo_ids, lambda { all.map(&:geo_id).uniq } # also tried: scope :supported_geo_ids, lambda { select('di

我有一个活动记录,其中有一个用例:我想在活动记录范围内使用map。以下是我的代码:

class SupportedGeoIdAndLocation < ActiveRecord::Base

   scope :supported_geo_ids,            lambda { all.map(&:geo_id).uniq }
   # also tried: scope :supported_geo_ids,            lambda { select('distinct geo_id').map(&:geo_id).uniq }
   scope :locations_for_geo_id, lambda { |geo_id| where(:geo_id => geo_id).map(&:location) }
end
但是当我使用supportedgeodandlocation.supported_geo_id时,我会得到空数组,而supportedgeodandlocation.all.map&:geo_id.uniq会给出我想要的结果

我正在寻找一种方法,这样就可以使用lambda一次性完成,而不是通过链接不同的方法和完全避免类函数

看来我用错了范围,请建议我什么是正确的方法

版本:padrino:0.10.5,ruby:ruby-1.9.3-p429,ActiveRecord:3.1.6

作用域应返回ActiveRecord::Relation,因此作用域可以与其他作用域或类方法等链接

如果要获取数组,请改用类方法

def self.supported_geo_ids
  all.map(&:geo_id).uniq
end

在我的一个模型中使用了一些类似的代码之后,我最终发现了Rails3.2中的错误消息,这与我的模型相同。接受的答案表示ActiveRecord隐式地假定作用域在ARel意义上是可链接的,而您返回的数组显然不是

因此,尽管您可以在类方法中做任何您想做的事情,但您必须按照@xdazz的答案定义自己,如果您坚持使用范围,那么您必须遵守ActiveRecord约定。乍一看,范围仅使用您提供的任何lambda定义类方法。这件事似乎有很多我看不出来的地方

更新

再摆弄几下,我想我已经尽可能接近了。您可以编写一个范围,返回刚刚支持的地理ID,即如下所示:

class SupportedGeoIdAndLocation < ActiveRecord::Base
  scope :supported_geo_ids,  lambda { select("distinct(geo_id)") }
end

请注意,现在不需要调用uniq,因为这已由范围中的distinct处理。从rails 4.0.2开始,ActiveRecord确实支持distinct方法,因此如果可以更新ActiveRecord gem,就不必使用字符串,因为Padrino不应该依赖它。

正如@patru所指出的,作用域只用于返回关系。它们不是用来返回值的。因此,您的问题是如何使作用域返回特定值?这是无法回答的

我的印象是,您认为类方法的设计很差,或者不是Rails的方式,但在本例中,我同意@xdazz的观点,认为它们是最好的解决方案

但是,我将以稍微不同的方式实现该方法:

def self.supported_geo_ids
  self.all(:select => "DISTINCT(geo_id)").map(&:geo_id)
end
这样,在数据库引擎中执行重复数据消除,并且只返回所需的值。这可能会使查询速度更快

在较新版本的Rails中,您可以这样编写:

def self.supported_geo_ids
  self.uniq.pluck(:geo_id)
end

如果出于某种原因,您仍然不想使用类方法,请解释原因,我将尝试想出一个解决方法。

您不需要映射使用Pulk,作用域:supported_geo_id,lambda{Pulk:geo_id}我使用的是旧版本的rails,此版本中未定义Pull。@PhilidorGreen:已更新。您使用的是padrino还是rails…?@Sevensacat:我使用的是padrino。可以。但是为什么作用域返回一个空的关系呢?事实上,我希望ruby有一些特性,我不必为此使用链接或类方法。
def self.supported_geo_ids
  self.uniq.pluck(:geo_id)
end