Установите значения как логические в массиве и измените положение в ruby ​​(Rails 5) - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть набор объектов через ActiveRecord, и мне нужно пройти через них, чтобы идентифицировать набор условий.

def get_smith_listings
  Listing.joins(:spec).where('specs.broker ilike ?', '%smith%')
end

@listings = Listings.all #actually a built query

@listings.sort_by { |item| item.get_smith_listings? ? 0 : 1 }

=> EXPLAIN for: SELECT "listings".* FROM "listings" INNER JOIN "specs" ON "specs"."listing_id" = "listings"."id" WHERE (specs.agent ilike '%smith%')
                                      QUERY PLAN
--------------------------------------------------------------------------------------
 Nested Loop  (cost=0.28..848.56 rows=1 width=668)
   ->  Seq Scan on specs  (cost=0.00..840.25 rows=1 width=4)
         Filter: ((agent)::text ~~* '%smith%'::text)
   ->  Index Scan using listings_pkey on listings  (cost=0.28..8.30 rows=1 width=668)
         Index Cond: (id = specs.listing_id)

(характер вопроса немного изменился, так как я сосредоточился на требуемом методе)

У меня проблемы с структурированием таким образом, что а) получает мойМетод распознан (новичок в помощниках) и устанавливает запрос для сортировки с использованием логического значения.

ОБНОВЛЕНИЕ: Для этого поиска разъяснений, это направление, в котором я пытаюсь решить эту проблему: https://www.mateoclarke.com/blog/2015/10/14/what-i-learned-boolean-ruby/

Ответы [ 2 ]

0 голосов
/ 25 апреля 2018

Enumerable # partition делает это: в результате получается массив из 2 массивов.Первый содержит все элементы, для которых блок является истинным, второй - ложные.

0 голосов
/ 25 апреля 2018

Вы можете сделать это следующим образом:

group = Listings.all.joins(:spec).where('specs.agent ilike ?', '%smith%') +
 Listings.all.joins(:spec).where.not('specs.agent ilike ?', '%smith%')

Таким образом, на групповую переменную будут сначала помещаться те, которые соответствуют условию, а после них - те, которые не

* 1005.* РЕДАКТИРОВАТЬ: не знаю точно, почему вам нужен отдельный метод для этого (так как способ, который я показал раньше, даст вам правильный порядок в любом случае).Но есть проблема с синтаксисом, который вы показали при редактировании: вы пытаетесь вызвать метод экземпляра, который вызывает весь метод ActiveRecord где (та же проблема, что и в ответе steenslag).Если вы хотите сделать так, как вы представили, я думаю, что этот способ должен работать лучше:
#this method should be on Listing model
def get_smith_listings?
  self.spec.broker.to_s.include?("smith")
end

@listings = Listings.includes(:spec).all #important to avoid n+1 queries

# here the 0 or 1 position will depende the true/false order you want
@listings.sort_by { |item| item.get_smith_listings? ? 0 : 1 }

Я до сих пор не понимаю, почему вы хотите сделать это так, и думаю, что, вероятно, есть лучший способ сделать то, что выхочу ... но сейчас я не могу помочь больше, чем это.Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...