Ruby:如何将Module中的方法包含在ActiveModel :: Serializer

时间:2015-04-29 07:32:45

标签: ruby-on-rails active-model-serializers rspec3

我正在尝试将辅助模块中的方法包含到ActiveModel::Serializer子类中,但由于某种原因,该方法没有显示出来。

这是我的简单助手模块:

module Helpers
  module Serialisers
    def enforce_zulu_time(attribute)
      define_method(attribute) do
        object.send(attribute).utc.iso8601 unless object.try(attribute).nil?
      end
    end
  end
end

这是我的测试序列化器

class TestSerialiser < ActiveModel::Serializer
  include Helpers::Serialisers
  attributes :updated_at

  enforce_zulu_time :updated_at
end

和我的序列化的简单对象

class TestItem
  include ActiveModel::SerializerSupport
  attr_reader :updated_at
  def initialize
    @updated_at = Time.now.utc
  end
end

和我的测试

describe Helpers::Serialisers do
  let(:item)       { TestItem.new }
  let(:serialiser) { TestSerialiser.new(item) }
  subject          { serialiser.attributes }

  it { expect(subject[:updated_at]).to be_zulu_time}
end

结果

`<class:TestSerialiser>': undefined method `enforce_zulu_time' for TestSerialiser:Class (NoMethodError)

但是,如果我只是在我的TestSerialiser中执行此操作

class TestSerialiser < ActiveModel::Serializer
  attributes :updated_at

  ['updated_at'].each do |attribute|
    define_method(attribute) do
      object.send(attribute).utc.iso8601 unless object.send(attribute).blank?
    end
  end
end

一切正常。

为什么我的enforce_zulu_time方法没有被包含在内?

1 个答案:

答案 0 :(得分:2)

include Helpers::Serialisers替换为extend Helpers::Serialisers,因为您需要使用类方法。

另一种解决方案是使用ActiveSupport::Concernsee doc

<强> 旁注

为了让您的代码免费灵活,我建议您为序列化程序创建自己的基类,例如:

class BaseSerializer < ActiveModel::Serializer
end

然后让所有序列化程序继承它。这样您就可以轻松添加功能。