6

我在我的 Rails 3.2 应用程序中遇到问题,其中通过 JSON 平稳发送的虚拟属性不在 params 哈希中的正确位置。好吧,这不是我所期望的。我的预期是否正确还有待观察。:)

我有一个使用标准虚拟属性模式的模型,如下所示:

class Track < ActiveRecord::Base
  def rating
    # get logic removed for brevity
  end

  def rating=(value)
    # set logic
  end

  def as_json(options={}) # so my method is in the JSON when I use respond_with/to_json
    super(options.merge(methods: [:rating]))
  end
end

发送到我的控制器的 JSON 如下所示:

{"id":1,"name":"Icarus - Main Theme 2","rating":2}

需要明确的是,name 和 id 不是虚拟的,rating 是。

在 rails 发挥作用之后,我最终在 params 哈希中得到了这个:

{"id"=>"1", "name"=>"Icarus - Main Theme 2", "rating"=>2, "track"=>{"id"=>"1", "name"=>"Icarus - Main Theme 2"}}

如您所见, id 和 name 使其成为嵌套的 :track 哈希,但 rating 没有。这是预期的行为吗?它打破了在控制器中使用嵌套散列的(有点)标准做法,因为嵌套散列不包含我需要的所有参数。

Track.update(params[:id], params[:track]) # :track is missing rating

谢谢你的帮助!

4

3 回答 3

7

我最近也遇到了这个问题。问题是,参数包装器正在查看您的模型 Track.attribute_names 以确定如何将数据映射到 :track => {params} 哈希中。如果您没有关联模型,默认情况下将根据控制器名称包装参数,并包含所有值:

class SinglesController < ApplicationController
  def create
    #params[:single] will contain all of your attributes as it doesn't 
    # have an activerecord model to look at.
    @track_single = Track.new(params[:single]) 
  end
end

您可以在控制器中调用 wrap_parameters 来告诉动作控制器在包装参数时要包含哪些属性,如下所示:

class TracksController < ApplicationController
  wrap_parameters :track, :include => :rating
  #other controller stuff below
end

在此处查看更多信息:http: //api.rubyonrails.org/classes/ActionController/ParamsWrapper.html

于 2012-10-03T20:23:38.867 回答
0

也许如果您rating在嵌套哈希中分配虚拟属性,如下所示:

def as_json(options={})
  super(options.merge(:track => {:methods => @rating}))
end

它会按照您预期的方式运行。

于 2012-07-25T12:37:39.510 回答
0

刚刚遇到这个问题并想出了一个相当不错的解决方案。将以下内容添加到您的 ApplicationController

wrap_parameters exclude: [:controller, :action, :format] + ActionController::ParamsWrapper::EXCLUDE_PARAMETERS

这样,所有内容都嵌套在您的资源下(Rails 添加到 params 哈希的内容除外),您不必再次附加到特定于控制器的 wrap_parameters 调用。:D

于 2016-05-09T21:24:23.617 回答