0

给定两个模型和一个控制器:

苹果

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_jsonApples.as_json.

这是预期的行为吗?在不使用 RABL 之类的东西的情况下,有什么干净的方法吗?我觉得这对我的需求来说太过分了。

4

1 回答 1

1

在伪代码中,哈希as_json方法的代码看起来像

def as_json(options={})
  Hash[collect {|key,element| [key.to_s,element.as_json(options)]}]
end

但是您的元素正在修改您传递给它的选项参数。哈希不知道这一点,因此将修改后的选项哈希传递给as json.

通常最好不要修改传递给您的参数,除非非常清楚这是可以的。我会将您的方法重写为

def as_json(options={})
  defaults = {:include => :not_apples}
  super(defaults.merge(options))
end
于 2012-07-12T07:17:50.940 回答