我有一个带有虚拟属性的模型,当模型呈现为JSON时,我希望将其包括在内。我做到了这一点:
def to_json(options={})
options[:methods] ||= [];
options[:methods] << :date_string;
super(options);
end
将date_string
方法添加到生成JSON时要呈现的属性列表中。
在我的控制器中,show动作会产生正确的结果,呈现date_string
,好像它只是一个普通的属性:
def show
@project = Project.find params[:id]
respond_to do |format|
format.html
format.json { render :json => @project }
end
end
但索引操作不包括date_string
:
def index
@projects = Project.all
respond_to do |format|
format.html
format.json { render :json => @projects }
end
end
有谁知道是否有可能让这个工作?我猜测它在呈现集合时没有使用特定于模型的to_json
。
编辑:看起来我现在应该使用as_json
- 我会看看是否能解决这个问题。
Edit2:我认为as_json
在这里没有任何区别。
答案 0 :(得分:2)
查看ActiveModel::Serialization docs,看起来您可以覆盖serializable_hash
方法以包含虚拟字段:
def serializable_hash(options)
super(options.deepmerge({:methods => :date_string}))
end
请注意,这会将其添加到所有序列化格式(即JSON和XML)。
如果这不起作用,请添加一些日志记录,以查看是否在集合案例中调用了该方法。
答案 1 :(得分:1)
as_json应该可行。 to_json将值转换为json并对其进行编码。 as_json在没有编码的情况下进行转换。数组在没有编码的情况下转换它们的对象,然后一次编码整个字符串,因此它是你的模型的as_json()方法,在数组被序列化时被调用:
https://github.com/rails/rails/blob/master/activesupport/lib/active_support/json/encoding.rb#L215
我能够在本地复制您的问题,这个解决方案对我有用:
def as_json(options={})
options ||= {} # need this because to_json without options will pass nil to as_json
options[:methods] ||= [];
options[:methods] << :date_string;
super(options);
end