Как использовать атрибуты ActiveRecord в Rails 5 для предоставления виртуального столбца - PullRequest
0 голосов
/ 21 февраля 2019

Я хочу добавить виртуальные столбцы в некоторые из моих моделей, но чтобы их значения возвращались операторами ActiveRecord, такими как Product.first, чтобы я мог использовать операторы, такие как Product.first.to_json, для вывода продукта с виртуальными столбцами назапрос API.

Значения столбцов зависят от других атрибутов модели.Я не хочу, чтобы эти столбцы были сохранены в базе данных.

Я пробовал это:

class Product < ApplicationRecord
  def total
    price + tax
  end
end

, но Product.first не включал общее количество.

class Product < ApplicationRecord
  attribute :total, :decimal, default: -> { 0.0 }
end

добавляет total: 0.0 к возвращенному объекту, но

class Product < ApplicationRecord
  attribute :total, :decimal, default: -> { price + tax }
end

завершается ошибкой с сообщениями, такими как

#<NameError: undefined local variable or method `price' for #<Class:0x0000557b51c2c960>>

и

class Product < ApplicationRecord
  attribute :total, :decimal, default: -> { 0.0 }

  def total
    price + tax
  end
end

все еще возвращает total: 0.0.

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

сумма:

  • таблица products не должна содержать столбец total.
  • доступ к Product через ActiveRecord должен возвращать объект Product, который включает total ключ с вычисленным значением, основанным на других атрибутах модели.

Возможно ли это?

I действительно не нужно заменятькаждый to_json вызов с большим количеством кода, вручную вставляющий эти виртуальные столбцы ...

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Переопределите as_json в вашей модели, чтобы включить ваш метод.

Это не будет включать итоговое значение в ваш извлеченный объект Product, но оно будет включать его при вызове .to_json объекта.

class Product < ApplicationRecord
  attribute :total, :decimal, default: -> { 0.0 }

  def total
    price + tax
  end

  def as_json(options = {})
    super(methods: [:total])
  end
end
0 голосов
/ 21 февраля 2019

Вы можете использовать methods опция

class Product < ApplicationRecord
  def total
    price + tax
  end
end

Product.first.to_json(methods: :total)
...