Как я могу привести значение строки перечисления к типу столбца? - PullRequest
0 голосов
/ 20 марта 2019

Мне нужно создать метод, который динамически фильтрует модель по столбцу. Он должен получить столбец, по которому я хочу фильтровать (называемый attr_name), operator как строку и value как строку.

Мне нужно сначала привести строковое значение к типу столбца базы данных, чтобы я мог затем выполнить SQL-запрос.

scope :filtered_by_attribute, (lambda do |attr_name, operator, value|
  comparing_value = Customer.attribute_types[attr_name].cast(value)
  casting_error = !value.nil? && comparing_value.nil?
  raise I18n.t('api.errors.unaplicable_customer_scope') if casting_error

  sql_query = sanitize_sql("#{attr_name} #{operator} ?")
  where(sql_query, comparing_value)
end)

Проблема выше, когда дело доходит до enums. Перечисления являются целыми числами в БД, но когда я выполняю приведение, он возвращает то же строковое значение, поскольку для рельсов это строка. Затем в запросе where он взрывается, поскольку в базе данных он сравнивает целочисленный столбец со строкой.

Знаете ли вы, как я приводил строковое значение в соответствии с типом столбца в базе данных?

Спасибо!

1 Ответ

1 голос
/ 20 марта 2019

Метод cast преобразует значение из пользовательского ввода, когда оно присваивается экземпляру.В случае enum, когда вы присваиваете строковое значение, оно остается строковым значением.Он преобразуется в целое число только тогда, когда он сохраняется в БД.

class Order < ActiveRecord::Base
  enum status: {confirmed: 1, cancelled: 2}
end

# this is where the `cast` method is called
@order.status = "cancelled"

# still a string since the `cast` method didn't do anything.
@order.status # => "cancelled"

Что вам действительно нужно, так это метод serialize.Он преобразует значение из типа ruby ​​в тип, который база данных знает для понимания.

Order.attribute_types["status"].serialize("cancelled") # => 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...