感谢马特,我做了一些挖掘并找到了 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
现在我只需要弄清楚我想如何支持集合。