Rails as_json有两个不相关的模型

时间:2012-07-12 03:22:27

标签: ruby-on-rails activerecord

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

苹果

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这样的东西,有没有干净的方法?我觉得这对我的需求来说太过分了。

1 个答案:

答案 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