2012-01-12 120 views
4

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

我不知道这是否是正确的方法。

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

+0

你可以随时执行你想要的任何原始SQL。 – 2012-01-12 06:52:16

+0

是sergio,但在这种情况下,我将不得不更改很多代码。因为我使用主动记录的查找方法,它已经在照顾生成查询。那么有没有一种方法可以在不使用原始sql查询的情况下集成group_concat?和thnx你的回应btw .. – Hitesh 2012-01-12 07:22:54

+0

如果你有这个问题的实际SQL查询..这里也发布。 – 2014-08-03 18:54:57

回答

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工作,拉每个用户连接到,我只需要像这样添加一个类的方法来对用户模型的各地区代码:

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: "[email protected]">,#<User email: "[email protected]">,#<User email: "[email protected]">,#<User email: "[email protected]">,#<User email: "[email protected]">] 

每个返回的对象有#regions_list属性读者,会给你连接到通过regions_users表用户的地区码的组拼接列表。

这可以用一个简单的调用被视为#map:

ruby > User.regions_listing.map { |u| [u.email, u.regions_list] } 
=> [["[email protected]", "0,1,2,3,4,5"], ["[email protected]", "1,2,5"], ["[email protected]", "0,4"], ["[email protected]", "3"], ["[email protected]", "2,3,4,5"]] 

注意,因为这是使用适当的AREL支持AR方法,它是可链接。也就是说,您可以将“.regions_listing”添加到任何针对用户模型的AR查询的末尾,它将为您提供用于查询您的查询的任何用户对象的组级联方法/数据。

这样:

ruby > User.where("users.email like 'b%'").regions_listing.map { |u| [u.email, u.regions_list] } 
=> [["[email protected]", "0,4"], ["[email protected]", "2,3,4,5"]] 

而且你还可以在你的制造#regions_list字段中的数据使用具有例如找到所有连接到两个区域0和区域4的用户得到:

ruby > User.regions_listing.having("regions_list LIKE '%0%4%'").map { |u| [u.email, u.regions_list] } 
=> [["[email protected]", "0,1,2,3,4,5"], ["[email protected]", "0,4"]] 
相关问题