首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用self.calculate时出现未定义的错误

使用self.calculate时出现未定义的错误
EN

Stack Overflow用户
提问于 2012-01-12 14:51:37
回答 1查看 221关注 0票数 4

我想在rails中执行mysql函数GROUP_CONCAT。我正在使用活动记录的计算方法。像这样的self.calculate(:group_concat,:id)

我不知道这是不是正确的方式。

有关于如何在rails中执行group_concat的想法吗?以及activerecord的find方法。

EN

回答 1

Stack Overflow用户

发布于 2014-10-02 06:31:52

正如@Camway上面提到的,使用适用于JOINing、SELECTing和GROUPing的Rails方法很容易做到这一点。举个例子,假设我有用户和区域,一个用户可以有0对多的区域,一个区域可以有0对多的用户。

下面是我的Region模型:

代码语言:javascript
复制
class Region < ActiveRecord::Base
  # attributes: id (integer), code (string)
  has_and_belongs_to_many :users
end

下面是我的用户模型:

代码语言:javascript
复制
class User < ActiveRecord::Base
  # attributes: id (integer), email (string)
  has_and_belongs_to_many :regions
end

当然,还有一个包含region_id和user_id整数字段的regions_users连接表。

为了让一个通用的GROUP_CONCAT能够提取每个用户所连接的所有区域的代码,我只需要在用户模型中添加一个如下所示的类方法:

代码语言:javascript
复制
class User < ActiveRecord::Base
  # attributes: id (integer), email (string)
  has_and_belongs_to_many :regions

  class << self
    def regions_listing
      joins(:regions)
      .select("DISTINCT users.email, GROUP_CONCAT(DISTINCT regions.region_code ORDER BY regions.region_code) AS regions_list")
      .group("users.email")
      .order("users.email")
    end
  end
end

因此,只需准备好这一小段代码,下面的代码就可以提取所有用户,并按电子邮件地址排序。

代码语言:javascript
复制
ruby > User.regions_listing
 => [#<User email: "joe@blow.com">,#<User email: "sally@mae.com">,#<User email: "billy@bob.com">,#<User email: "jane@doe.com">,#<User email: "big@ed.com">]

这些返回的对象中的每一个都有一个#regions_list属性读取器,它将为您提供通过regions_users表附加到该用户的地区代码的组连接列表。

这可以通过对#map的简单调用来看到:

代码语言:javascript
复制
ruby > User.regions_listing.map { |u| [u.email, u.regions_list] }
 => [["joe@blow.com", "0,1,2,3,4,5"], ["sally@mae.com", "1,2,5"], ["billy@bob.com", "0,4"], ["jane@doe.com", "3"], ["big@ed.com", "2,3,4,5"]]

请注意,由于这使用了适当的AR支持的AR方法,因此它是chainable。也就是说,您可以将".regions_listing"添加到几乎任何针对用户模型的AR查询的末尾,它将为您的查询获取的任何用户对象提供组连接方法/数据。

因此:

代码语言:javascript
复制
ruby > User.where("users.email like 'b%'").regions_listing.map { |u| [u.email, u.regions_list] }
 => [["billy@bob.com", "0,4"], ["big@ed.com", "2,3,4,5"]]

您还可以使用HAVING来获取您的制造的#regions_list字段中的数据,例如,查找连接到区域0和区域4的所有用户:

代码语言:javascript
复制
ruby > User.regions_listing.having("regions_list LIKE '%0%4%'").map { |u| [u.email, u.regions_list] }
 => [["joe@blow.com", "0,1,2,3,4,5"], ["billy@bob.com", "0,4"]]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8831176

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档