Rails Scope: выберите отдельный заголовок со значениями - PullRequest
3 голосов
/ 09 февраля 2012

У меня проблемы с запросом SQL в области видимости.Мне нужно вернуть коллекцию уникальных Project.titles и сопровождающие их идентификаторы для использования в форме.

Я могу получить отдельный заголовок, используя

scope :unique_title, select("DISTINCT title")

Но я не получаюзначение в результирующих параметрах

= project_form.input :id, collection: current_user.projects.unique_title

Результат:

<select>
  <option value>Item 1</option>
  <option value>Item 2</option>
  <option value>Item 3</option>
</select>

Итак, добавление идентификатора в мою область:

scope :unique_title, select("DISTINCT title").select("id")

Результат даетмне значения, но теперь мой выбор DISTINCT больше не существует:

<select>
  <option value="1">Item 1</option>
  <option value="2">Item 2</option>
  <option value="3">Item 3</option>
  <option value="4">Item 2</option>
  <option value="5">Item 2</option>
  <option value="6">Item 2</option>
</select>

Ответы [ 3 ]

7 голосов
/ 09 февраля 2012

Я думаю, что вы не сможете выбрать другое поле вместе с Distinct, сохранившим свою отличительность.

Я думаю, вы можете искать GROUP BY, который можно использовать в Rails следующим образом:

scope :unique_title, select("id, title").group("title")

Но при этом будет выбран только первый из группы с таким же названием. Если вы хотите получить все записи, но должны сгруппировать их в соответствии с их заголовком, вам нужно получить все записи и затем сгруппировать их из Ruby.

scope :titles, select("id, title")

тогда где вы используете прицел, вы sh:

Model.titles.all.group_by(&:title).each do |distinct_title, records|
  # do something with the distinct title and records having that distinct title
end
0 голосов
/ 10 февраля 2012

Я использовал другой подход для решения этой проблемы.

Новый столбец в моей модели проекта

$ rails g migration add_template_to_project template:boolean

Добавлен в модель

before_create :check_if_exists

def check_if_exists
  toggle!(:template) if title.exists?
end

ТогдаОбъем может быть:

scope :unique_title, select("id, title").where(template: true)

Работает шарм

0 голосов
/ 09 февраля 2012

Я давно не делал SQL il, так что, возможно, это не так, но я бы пошел с .select("id, title DISTINCT)

PS: Если вы используете Rails 3.2, вы можете использовать explain, чтобы увидеть, какой запрос фактически используется (по крайней мере, я думаю, что вы можете, еще не пробовал) и почему это не работает, как вы ожидаете.

...