给出两个模型和一个控制器:
苹果
class Apples < ActiveRecord::Base
belongs_to :not_oranges
...
def as_json(options={})
opts = {:include => [:not_oranges]}
super(options.reverse_merge! opts)
end
end
橙子
class Oranges < ActiveRecord::Base
belongs_to :not_apples
...
def as_json(options={})
opts = {:include => [:not_apples]}
super(options.reverse_merge! opts)
end
end
搜索控制器
class SearchController < ApplicationController
a = Apples.search params[:q]
o - Oranges.search params[:q]
@results = {
:apples => a,
:oranges => o
}
respond_to do |format|
format.json { render :json => @results }
end
如您所见,这两个模型完全不相关,并且在:include
定义中都有不同的as_json
选项。
如果搜索查询仅点击苹果或仅点击橙子,则所有工作都按预期工作,但一旦两个对象都不为空,我得到:
undefined method `not_apples' for #<Oranges:0x00000004af8cd8>
似乎正在合并两个as_json
定义,或Oranges.as_json
正在覆盖Apples.as_json
。
这是预期的行为吗?没有使用像RABL这样的东西,有没有干净的方法?我觉得这对我的需求来说太过分了。
答案 0 :(得分:1)
在伪代码中,散列as_json
方法的代码看起来像
def as_json(options={})
Hash[collect {|key,element| [key.to_s,element.as_json(options)]}]
end
但是你的元素正在修改你传递给它的options参数。 Hash没有意识到这一点,因此将修改后的选项哈希传递给as json
。
通常最好不要修改传递给你的参数,除非很明显这是正常的。我将你的方法重写为
def as_json(options={})
defaults = {:include => :not_apples}
super(defaults.merge(options))
end