【问题标题】:Virtual attribute not moved to the model hash inside params虚拟属性未移动到参数内的模型哈希
【发布时间】:2012-02-19 22:54:41
【问题描述】:

我在 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

感谢您的帮助!

【问题讨论】:

  • 你能粘贴提交的表单吗,看起来它的范围不适合跟踪

标签: ruby-on-rails-3 virtual-attribute


【解决方案1】:

我最近也遇到了这个问题。问题是,参数包装器正在查看您的模型 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

【讨论】:

  • 我遇到了类似的问题,在使用 wrap_parameters 时,如果我有许多其他非虚拟属性,我必须将它们全部写入包含数组。否则它们不会包含在请求哈希中,如何以简单的方式做到这一点?因为我只有一个想要包含在请求哈希中的虚拟属性?谢谢
【解决方案2】:

也许如果你像这样在嵌套散列中分配rating 虚拟属性:

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

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

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-22
      • 1970-01-01
      • 2019-06-30
      • 2013-03-11
      • 2018-04-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多