Переопределение методов столбца ActiveRecord с помощью Mixin - PullRequest
1 голос
/ 10 марта 2011

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

class MyClass
  include TimeZonify
  tz_column :col1, :col2
end

Мой миксин явно неправильный, но выглядит примерно так:

module TimeZonify
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods

    def tz_column(*columns)
      columns.each do |column|
        instance_eval do   # <-- obviously this block does not get executed
          <<-CODE
            def #{column}
              super.in_time_zone("Lima")
            end
          CODE
        end
      end
    end

  end

end

Так что теперь, когда я звоню MyClass.new.col1, это больше не будет в UTC, а вместо этого в любом часовом поясе, который пользователь имеет в своем профиле.

1 Ответ

1 голос
/ 10 марта 2011

Если вы используете Rails, то поддержка часовых поясов должна работать из коробки.И вы можете иметь различный часовой пояс для каждого пользователя .


Я бы не рекомендовал переопределять методы доступа к дате / времени, потому что тогда вам также потребуется переопределить сеттер.

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

original = it.effective_at
it.effective_at = it.effective_at # it +TimeZone
it.effective_at = it.effective_at # it +TimeZone
original == it.effective_at # => false - every assignment actually changes the time by +TimeZone

Но если вам нужен ярлык для отображения, вместо этого ярекомендовал бы использовать расширение этого метода:

it.effective_at_local

, которое может быть реализовано с помощью mixin:

module TimeZonify
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods

    def tz_column(*columns)
      columns.each do |column|
        instance_eval do
          <<-CODE
            def #{column}_local
              #{column}.in_time_zone("Lima")
            end
          CODE
        end
      end
    end

  end

end

BTW, на соответствующей заметке вы можетеиспользуйте TimeZone .

...