【问题标题】:Custom to_json method not being called in Rails app在 Rails 应用程序中未调用自定义 to_json 方法
【发布时间】:2011-03-13 11:11:57
【问题描述】:

我有一个 Ruby on Rails 应用程序,我正在为相关的 iPhone 应用程序开发一个 API。

我已经覆盖了我的 Item 模型的 to_json 方法,以从我在 iPhone 应用程序中需要的 API 请求返回一些自定义信息。

但是,当我使用内置 rails to_json 方法并将我的 Item 模型作为关联参数包含时,我的 Item#to_json 方法不会被调用,而只会调用 AR 对象上的默认 to_json。

查看以下代码 (@api_user is a User model object)

    render :json => @api_user.to_json( :include => { :friends => { :include => :items, :except => :api_token } } )

我包含friends 关联,而后者又包含items 关联,但正在调用 Item 上的默认 to_json,而不是我的自定义 to_json。

我错过了什么?

这是我的Item#to_json 方法

  def to_json(options={})
{
  :id => self.id,
  :name => name,
  :description => description,
  :url => url,
  :quantity => quantity,
  :price_range_raw => price_range,
  :price_range => human_readable_price_range( price_range ),
  :can_be_purchased => can_be_purchased?,
  :completely_purchased => completely_purchased?,
  :remaining_qty => remaining_quantity,
  :thumb_photo_url => photo.url(:thumb),
  :small_photo_url => photo.url(:small),
  :large_photo_url => photo.url(:large),
  :priority_raw => priority,
  :priority => human_readable_priority( priority )
}.to_json

结束

没有其他模型覆盖 #to_json 方法

【问题讨论】:

  • 你能展示你的to_json方法吗?我最初的猜测是Userto_json 方法不会递归调用Item 之一,或者您的to_json 方法采用不同的参数,而是调用了某种method_missing 魔术方法。
  • 我正在深入研究源代码,我的猜测是用于枚举的 ActiveSupport JSON 编码器不会在每个项目上调用 to_json,而是将整个数组序列化为一个。我可能不得不编写我自己的映射函数,我猜想像我想要的那样传回数据

标签: ruby-on-rails ruby json api


【解决方案1】:

难道没有更直接的方法来覆盖 to_json 方法吗?使用 Devise 并不能解决一般问题。我可能希望选择不封送特定对象的某些属性的原因有很多,因此需要自定义方法。

【讨论】:

    【解决方案2】:

    您使用的是设计吗?如果是这样,他们会覆盖 to_json 和 to_xml 方法(谢谢,伙计们)。

    来自设计来源:

      %w(to_xml to_json).each do |method|
        class_eval <<-RUBY, __FILE__, __LINE__
          def #{method}(options={})
            if self.class.respond_to?(:accessible_attributes)
              options = { :only => self.class.accessible_attributes.to_a }.merge(options || {})
              super(options)
            else
              super
            end
          end
        RUBY
      end
    

    【讨论】:

    • 这个方法仍然调用super(),所以它仍然会包含我的自定义方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多