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

时间:2012-01-12 06:51:37

标签: ruby-on-rails redmine

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

我不知道这是否正确。

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

1 个答案:

答案 0 :(得分:0)

正如@Camway上面所说,使用适当的Rails方法轻松完成JOINing,SELECTing和GROUPing。例如,假设我有用户和区域,用户可以有0到多个区域,区域可以有0到多个用户。

这是我的区域模型:

class Region < ActiveRecord::Base
  # attributes: id (integer), code (string)
  has_and_belongs_to_many :users
end

这是我的用户模型:

class User < ActiveRecord::Base
  # attributes: id (integer), email (string)
  has_and_belongs_to_many :regions
end

当然,还有 regions_users 连接表与region_id和user_id整数字段。

为了获得通用的GROUP_CONCAT工作,它可以提取每个用户所附加的所有区域的代码,我只需要向User模型添加这样的类方法:

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

因此,只需使用相应的代码,以下内容将拉动所有用户,按电子邮件地址排序。

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:

可以看到这一点
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"]]

请注意,由于这是使用适当的AREL支持的AR方法,因此可链接。也就是说,您可以将“。regions_listing”添加到几乎任何针对User模型的AR查询的末尾,它将为您提供查询选择的任何用户对象的组连接方法/数据起来。

因此:

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的所有用户:

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"]]