感谢马特,我做了一些挖掘并找到了 dm-serializer 的 to_json 方法的 :method 参数。他们的 to_json 方法相当不错,基本上只是 as_json 辅助方法的包装器,所以我通过添加几行来覆盖它:
if options[:include_attributes]
options[:methods] = [] if options[:methods].nil?
options[:methods].concat(model.attributes).uniq!
end
完成的方法覆盖如下所示:
module DataMapper
module Serializer
def to_json(*args)
options = args.first
options = {} unless options.kind_of?(Hash)
if options[:include_attributes]
options[:methods] = [] if options[:methods].nil?
options[:methods].concat(model.attributes).uniq!
end
result = as_json(options)
# default to making JSON
if options.fetch(:to_json, true)
MultiJson.dump(result)
else
result
end
end
end
end
这与我添加到与我的模型一起使用的基本模块中的属性方法一起使用。相关部分如下:
module Base
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def attr_accessor(*vars)
@attributes ||= []
@attributes.concat vars
super(*vars)
end
def attributes
@attributes || []
end
end
def attributes
self.class.attributes
end
end
现在我原来的例子:
require 'json'
class Person
include DataMapper::Resource
include Base
property :id, Serial
property :first_name, String
attr_accessor :last_name
end
ps = Person.new
ps.first_name = "Mike"
ps.last_name = "Smith"
p ps.to_json :include_attributes => true
使用新的选项参数按预期工作。
为了有选择地获得我想要的属性而不必做额外的工作,我可以做的就是将属性名称传递给 :methods 参数。
p ps.to_json :methods => [:last_name]
或者,因为我已经Base
上课了:
p ps.to_json :methods => Person.attributes
现在我只需要弄清楚我想如何支持集合。