неопределенная ошибка при использовании self.calculate - PullRequest
4 голосов
/ 12 января 2012

Я хочу выполнить функцию mysql GROUP_CONCAT в рельсах.Я использую метод расчета активной записи.как этот self.calculate (: group_concat,: id)

Я не знаю, если это правильный путь.

Есть идеи о том, как выполнить group_concat в рельсах?вместе с методом поиска activerecord.

1 Ответ

0 голосов
/ 02 октября 2014

Как отмечает @Camway выше, это легко сделать, используя подходящую методологию Rails для СОЕДИНЕНИЯ, ВЫБОРА и ГРУППИРОВАНИЯ. Например, скажем, у меня есть пользователи и регионы, у пользователя может быть от 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

Конечно, есть также таблица соединений region_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">]

Каждый из этих возвращаемых объектов имеет средство чтения атрибутов # region_list , которое предоставит вам объединенный в группу список кодов для регионов, прикрепленных к этому пользователю через таблицу region_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"]]

Обратите внимание, что поскольку здесь используются соответствующие AR-методы с поддержкой AREL, он цепочечный . Таким образом, вы можете добавить ". Region_listing" в конце практически любого AR-запроса к модели User, и он даст вам метод / данные, объединенные в группу для любых объектов User, выбранных вашим запросом. .

Как таковой:

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

И вы также можете получить данные в вашем производственном поле #regions_list, используя HAVING, например, чтобы найти всех пользователей, подключенных к региону 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"]]
...