Я работаю с Rails/угловым приложением, которое сохраняет значения температуры. Температуры всегда хранятся в градусах Цельсия в базе данных. Эти значения температуры могут отображаться пользователю в градусах Цельсия или Фаренгейта, исходя из предпочтений пользователя.Перехват вызовов приемника и сеттера в Rails для обработки данных
Приложение может также предупредить пользователя, если температура достигает определенного значения. Это важно, потому что пользователь может ввести значение предупреждения в Fahrenheit, но его необходимо преобразовать в цельсию до его сохранения в базе данных. Эти значения alert
также находятся в другой таблице, чем сами показания температуры, поэтому решение идеально подходит для разных моделей.
Таким образом, по существу, мне нужно найти лучшее место и стратегию для управления значением, когда они считываются и сохраняются в базу данных. Мы пробовали пару разных вещей, но я стараюсь реорганизовать их в удобное поддерживаемое решение, которое включает в себя как можно меньше кодовых путей.
Для отображения показаний температуры в режиме отображения мы использовали проблему с контроллером в ReadingsController
. Это сопоставляется с ReadingPresenter
, который будет конвертировать в Fahrenheit, если пользователь имеет это предпочтение.
class ReadingPresenter
include ApplicationHelper
def initialize(sensor_reading, sample_type)
@model = sensor_reading
@sample_type = sample_type
end
def value
if @sample_type.temperature?
TemperatureService.for_current_user @model.value
else
@model.value
end
end
end
Это прекрасно работает, когда нам нужно отобразить чтение Fahrenheit, который уже хранится, но так как это ведущий он явно не будет работать, когда нам нужно изменить введенное пользователем значение Фаренгейта alert
в градусах Цельсия, чтобы быть хранящихся в базе данных.
В этом случае мы создали модельную проблему, которая имеет before_save
, after_save
и after_find
обратные вызовы для управления.
module TemperatureAttributes
extend ActiveSupport::Concern
module ClassMethods
def temperatures(*temperature_attributes)
options = temperature_attributes.extract_options!
before_save TemperatureScaleConverter.new(temperature_attributes, options[:if])
after_save TemperatureScaleConverter.new(temperature_attributes, options[:if])
after_find TemperatureScaleConverter.new(temperature_attributes, options[:if])
end
end
end
Это действительно работает, но вы можете видеть, что это совершенно другой путь кода. Я должен представить, что есть лучший способ справиться с такой ситуацией в Rails.
Я экспериментировал с Ruby's prepend method, чтобы перехватить вызовы и так же рассмотрел использование alias_method_chain
. Я также думал о попытке условно использовать представления базы данных для преобразования значений на самом низком уровне.
Я не ищу, чтобы вы разрешили мою проблему для меня, но , если у вас есть какие-либо советы по наилучшему способу перехвата вызовов getter и setter в Rails по моделям Мне бы очень хотелось его услышать.
Спасибо, что нашли время ответить - я ценю это. Мне нравится использование 'after_initialize' в объекте Presenter. Я об этом не думал. Если я не понимаю, я не мог использовать блок 'after_initialize', чтобы помочь с ** установкой ** значения в градусах Цельсия, когда передается значение Фаренгейта, правильно? – JackCollins
Это немного сложно ответить, не видя всей базы кода, и мой ответ неясен в результате. Я думаю, что вы правы, но я думаю, что многие проблемы уходят, если вы используете температуру
jjk