Как я могу привести строковое значение перечисления к типу столбца?

#ruby-on-rails #activerecord

#ruby-on-rails #activerecord

Вопрос:

Мне нужно создать метод, который динамически фильтрует модель по столбцу. Он должен получить столбец, по которому я хочу отфильтровать (вызываемый 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? amp;amp; 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 . Перечисления — это целые числа в базе данных, но когда я выполняю приведение, оно возвращает то же строковое значение, поскольку для rails это строка. Затем в запросе where происходит сбой, поскольку в базе данных он сравнивает столбец integer со строкой.

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

Спасибо!

Комментарии:

1. Покажите пример вызова области видимости с атрибутом enum.

Ответ №1:

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