Необычное поведение при применении областей для фильтрации - PullRequest
0 голосов
/ 03 июня 2019

У меня есть модель CoffeeShop со столбцом "wifi_restrictions" - целочисленное значение, которое представляет количество часов, которое вы можете использовать Wi-Fi.

Я использую гем scopes и хотел бы, чтобы, еслиЯ получаю значение в параметрах «0», затем он возвращает все экземпляры CoffeeShop, где wifi_restrictions = 0.

Я пробовал два метода для реализации этого.

Метод 1:

В моей форме у меня есть следующее:

<input type="checkbox" name="no_wifi_restrictions" value="0">

В моей модели у меня есть:

scope :wifi_restrictions, -> hours { where(wifi_restrictions: hours) }

И в моем контроллере:

has_scope :wifi_restrictions, type: :integer

Результат: неопределенный метод `any? 'для nil: NilClass

(я получаю это, даже если нет никаких параметров, заданных для областей фильтрации, которые я не могу обернуть вокруг).


Метод 2:

В этом методе я попытался определить новую область видимости "no_wifi_restrictions".

В моей форме у меня есть следующее:

<input type="checkbox" name="no_wifi_restrictions" value="true">

Модель:

scope :no_wifi_restrictions, -> { where(wifi_restrictions: 0) }

Контроллер:

has_scope :no_wifi_restrictions, type: :boolean

Результат: корректно фильтруется, когда значение равно «true» (no_wifi_restrictions = true), но когда значение равно «false» (no_wifi_restrictions = false), возвращаются все экземпляры,В консоли, если я ищу CoffeeShop.no_wifi_restrictions, это фильтрует правильно.Но если я выполняю поиск в CoffeeShop.where (no_wifi_restrictions: true) или CoffeeShop.where (no_wifi_restrictions: false), то я не получаю ни одного экземпляра, возвращенного ни для одного из них.Так что я не уверен, как это работает даже в 50% случаев (и я не уверен, как выяснить, что происходит под капотом).

Ответы [ 2 ]

0 голосов
/ 06 июня 2019

ОК, поэтому я подумал, что следующий код по существу преобразует целочисленное значение в логическое при вызове метода с областью действия.

:no_wifi_restrictions, ->{ where(wifi_restrictions: 0) }

Так что я подумал, что, если я отправлю свои параметры no_wifi_restrictions = true, он вернет все экземпляры CoffeeShop, которые теперь возвращаются, если я ищу в консоли:

CoffeeShop.no_wifi_restrictions.

Однако это не так. Потому что в моих параметрах он передает значение. Поэтому, когда я пытаюсь это сделать, с параметром "true" я получаю:

wrong number of arguments (given 1, expected 0)

Я нашел следующее решение:

scope :no_wifi_restrictions, -> hours { where(wifi_restrictions: hours) }

, который также можно записать так:

scope :no_wifi_restrictions, -> hours { where("wifi_restrictions = ?", hours) }

Это позволяет передавать аргумент в область (часы). Так что в этом случае я передаю ему значение «0» в параметрах, и он будет запускать следующее:

CoffeeShop.where(wifi_restrictions: 0)

По сути, значение «часы» не нужно для моих нужд, потому что я действительно не хочу или не нуждаюсь в аргументе, просто я должен предоставить значение в параметрах (если я не ошибаюсь, я также пытался удаление атрибута значения, но это приводит к значению по умолчанию «on»).

Следовательно, следующее также будет работать, даже если переданный аргумент по существу избыточен:

scope :no_wifi_restrictions, -> hours { where("wifi_restrictions = 0", hours) }

В этом случае я мог бы действительно дать любое значение в параметрах, например:

value="this_is_a_useless_param"

... и он все еще будет работать, потому что все, что ему нужно, это передать аргумент в область действия.

Возможно, кто-то знает более аккуратный способ достижения этого, но сейчас это сработало для меня.

0 голосов
/ 05 июня 2019

Следующие строки не будут работать:

CoffeeShop.where(no_wifi_restrictions: true)
CoffeeShop.where(no_wifi_restrictions: false)

Эти строки пытаются получить все кафе, где столбец no_wifi_restrictions имеет значение true или false, и я думаю, что в кафе не существует этого столбца.

Если значение параметра равно true, вы хотите, чтобы область возвращала все CoffeeShops, где wifi_restrictions = 0, а в противном случае она должна возвращать все CoffeeShops, где wifi_restrictions> 0.

Может быть, также проще добавить логический столбец для ограничений Wi-Fi. Похоже, вы сейчас пытаетесь сравнить логические числа с целыми числами.

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