【问题标题】:problem using 'as_json' in my model and 'render :json' => in my controller (rails)在我的模型中使用 'as_json' 和在我的控制器(rails)中使用 'render :json' => 的问题
【发布时间】:2011-03-20 01:06:31
【问题描述】:

我正在尝试创建一个独特的 json 数据结构,但遇到了一个我似乎无法弄清楚的问题。

在我的控制器中,我正在做:

favorite_ids = Favorites.all.map(&:photo_id)
data = { :albums => PhotoAlbum.all.to_json,
         :photos => Photo.all.to_json(:favorite => lambda {|photo| favorite_ids.include?(photo.id)}) }

render :json => data

在我的模型中:

def as_json(options = {})
  { :name => self.name,
    :favorite => options[:favorite].is_a?(Proc) ? options[:favorite].call(self) : options[:favorite] }
end

问题是,rails 将“照片”和“专辑”的值(在我的数据哈希中)编码为 JSON 两次,这会破坏一切......我可以让它工作的唯一方法是如果我调用 ' as_json' 而不是 'to_json':

data = { :albums => PhotoAlbum.all.as_json,
         :photos => Photo.all.as_json(:favorite => lambda {|photo| favorite_ids.include?(photo.id)}) }

但是,当我这样做时,我的 :favorite => lambda 选项不再使其成为模型的 as_json 方法......所以,我要么需要一种方法来告诉 'render :json'不要对哈希值进行编码,这样我就可以自己对值使用“to_json”,或者我需要一种方法来让传递给“as_json”的参数真正显示在那里......

我希望这里有人可以提供帮助...谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby json


    【解决方案1】:

    好吧,我放弃了……我通过添加自己的数组方法来处理对集合执行的操作,从而解决了这个问题。

    class Array
    
      def to_json_objects(*args)
    
        self.map do |item|
          item.respond_to?(:to_json_object) ? item.to_json_object(*args) : item
        end
    
      end
    
    end
    
    class Asset < ActiveRecord::Base
    
      def to_json_object(options = {})
        {:id => self.id, 
         :name => self.name,
         :is_favorite => options[:favorite].is_a?(Proc) ? options[:favorite].call(self) : !!options[:favorite] }
      end
    end
    
    class AssetsController < ApplicationController
    
      def index
    
        @favorite_ids = current_user.favorites.map(&:asset_id)
    
        render :json => {:videos => Videos.all.to_json_objects(:favorite => lambda {|v| @favorite_ids.include?(v.id)}),
                         :photos => Photo.all.to_json_objects(:favorite => lambda {|p| @favorite_ids.include?(p.id)}) }
    
      end
    end
    

    【讨论】:

      【解决方案2】:

      我想运行这行代码

      render :json => {:key => "value"}
      

      等于

      render :text => {:key => "value"}.to_json
      

      换句话说,不要同时使用to_json:json

      【讨论】:

      • 但是......我需要实际的对象是 json。 {:foo => @foo.to_json} 并不意味着它是一个 json 对象。这意味着它是一个 ruby​​ 散列,其值以 json 编码......
      • 你不能用render :text =&gt; json_object吗?
      • 我没有 json 对象。那就是问题所在。如何将 {:foo => "{\"json_foo\":\"json_foo\"}" } 部分 json 转换为 "{\"foo\":{\"json_foo\":\"json_foo\" }}" 这将是一个 PURE json 对象......这就是问题所在。
      • 此外,你所说的无论如何都不准确..即使你渲染 :text => "{\"foo\":{\"json_foo\":\"json_foo\"}}" ,其中的 ajax 响应对象将不会被识别为 json,它将被视为文本并需要被转换。所以底线是,要让它工作将需要在控制器和 javascript 级别上进行大量黑客攻击。
      猜你喜欢
      • 1970-01-01
      • 2015-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-06
      相关资源
      最近更新 更多