Как написать запрос ActiveRecord для особого случая - PullRequest
0 голосов
/ 10 мая 2018

Я использую Ruby on Rails 5.1, и у меня есть модель Entry, которая имеет атрибут word. Может быть несколько Entries с одним и тем же словом, поскольку их уникальность основана на word плюс другое поле. В контроллере я создаю выпадающий селектор @unique_entries, который должен включать только первый экземпляр Entry.word.

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

Последнее, что я попробовал, было что-то вроде этого псевдокода (извините, я удалил реальный код после сбоя):

all_entries = Entry.all.order(word: :asc)
unique_entries = []
all_entries.each do |entry|
  if unique_entries.include?(entry.word)
    use the index to delete this record from all_entries
  else
    unique_entries << entry.word
  end
end

По крайней мере, в моей голове это должно пройти через коллекцию all_entries, проверяя, находится ли каждый entry.word в unique_entries, который начинается как пустой массив. Если нет, то entry.word добавляется к unique_entries. Если это так, он удаляет entry из коллекции ActiveRecord all_entries, поскольку это означает, что он уже существует. Этот подход не удался, удаляя содержимое из массива образцов непоследовательно.

Я понимаю, что это медленный путь, и он подойдет только тогда, когда у меня есть небольшое количество записей, поэтому я открыт для предложений других способов подойти к этому. Я все еще относительно новичок в разработке RoR, и мне еще не приходилось иметь дело с очень сложными запросами ActiveRecord, поэтому, пожалуйста, не наступайте мне на голову, потому что я уже не сделал то, что было бы "очевидно" для вас. Спасибо.

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Вы можете позволить базе данных выполнять работу, используя вместе distinct и pluck:

Entry.distinct.pluck(:word)

И если вы хотите, чтобы база данных выполняла сортировку:

Entry.distinct.order(:word).pluck(:word)

Последний должен заканчиваться использованием SQL следующим образом:

select distinct word from entries order by word
0 голосов
/ 10 мая 2018

Попробуйте:

@unique_entries = Entry.pluck(:word).uniq

Или:

@unique_entries = Entry.all.order(word: :asc).pluck(:word).uniq

Для сортировки.

Чтобы быть немного более информативным, рассмотрим:

@unique_entry_words = Entry.all.order(word: :asc).pluck(:word).uniq

(так как массив - это набор уникальных входных слов, а не уникальных записей)

Конечно, слишком короткое значение mu - это правильно, и это было бы лучше как:

Entry.distinct.order(:word).pluck(:word)

Если, OTOH, вы пытаетесь получить массив, состоящий из первого экземпляра каждого Entry для данного word (не уверен, что это то, что вам нужно, но этот комментарий о «используйтеИндекс для удаления ... »предполагает, что это может быть), вы можете попробовать что-то вроде:

Entry.all.order(:word).group_by(&:word).map{|k,v| v.first}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...