【问题标题】:Ruby on Rails - PUT Method Creates Extra Params EntryRuby on Rails - PUT 方法创建额外的参数条目
【发布时间】:2015-07-01 00:13:26
【问题描述】:

因此,我在为移动客户端创建的 RESTful API 实现端点时观察到一些奇怪的行为。我正在使用 PUT 方法更新 User 模型上的属性。我将用户的 id 作为 URL 参数和要在 JSON 对象中更新的值发送。一切似乎都很好,但是当我通过 rails 日志检查参数时,我发现了一些奇怪的东西。由于某种原因,有一个额外的参数被发送到后端,我似乎无法解释。以下是我从移动客户端调用此端点时看到的日志:

Parameters: {"enable_security"=>true, "id"=>"7d7fec98-afba-4ca9-a102-d5d71e13f6ce", "user"=>{}}

如上所示,附加的"user"=>{} 附加到参数条目列表中。当我打印出 params 对象时,我也看到了这一点。我似乎无法解释这是从哪里来的。为了安全起见,我还检查了移动客户端,并且在代码中没有任何地方可以发送带有密钥user 的参数。这让我很困惑,让我觉得我错过了一些相当简单的东西。为什么会有一个带有user 键的空对象被发送到后端 RESTful API?

更新以提供更多信息

这是当用户点击更新用户User模型的端点时调用的代码:

  #PUT /:id/user/update_security_settings
  def update_security_settings
    @user = User.find_by_id(params[:id])
    @user.advanced_security_enabled = params[:enable_security]

    respond_to do |format|
      if @user.save
        response = {:status => "200", :message => "User's security settings updated."}
        format.json { render json: response, status: :ok }
      else
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

针对用户评论的更新

以下是与user_controller 相关的路由,该视图控制器定义了处理创建和更新User 模型的所有端点。

post '/user/upload_profile', to: 'user#upload_profile'
get '/:id/user', to: 'user#find_user'
put '/:id/user/update_security_settings', to: 'user#update_security_settings'
resources :user, :defaults => { :format => 'json' }

【问题讨论】:

  • 你能把你提交的表格贴出来吗,如果我没记错的话,我相信那里有一个 User.new。
  • 没有 RESTFul api 的形式。我可以发布命中端点时调用的代码吗?这是你的意思吗? @Coderhs

标签: ruby-on-rails ruby put restful-architecture


【解决方案1】:

检查你的配置

config/initializers/wrap_parameters.rb

wrap_parameters format: [] 此列表不应包含 json,然后它将参数包装到控制器的根目录中以获取所有 json 请求。参考api文档

【讨论】:

    【解决方案2】:

    这条评论真的反映了你的实际路线吗?

    #PUT /:id/user/update_security_settings

    我希望它改为/user/:id/update_security_settings

    您能否向我们展示您的 config/routes.rb - 我的疯狂猜测是,您的路线以某种方式配置为期望实际的嵌套用户参数,您不发送(当然),因此在日志中显示为空。

    更新: 你的一些路线很不寻常。您实际上不需要 find_user 路由,因为它应该包含在 resources :user 下作为 show 操作(前提是您在控制器中定义了 show 方法,这是检索单个资源项的默认方法;因此不需要 find_user)

    对于像您的 update_security_settings 操作这样的自定义路由,我建议坚持使用默认模式,例如 resource/:id/action,并将其嵌套在默认的资源丰富的路由中。将 id 放在资源之前是非常不寻常的、令人困惑的,并且实际上可能与您的问题有关(尽管我不确定)。尝试清理您的路线。rb 像这样:

    # notice that resources expects the plural form :users
    resources :users do
      member do 
        patch :update_security_settings
        post :upload_profile
        # any other custom routes
      end
    end
    

    这将产生像GET /users(索引)、GET /users/1(显示)和PATCH /users/1/update_security_settings这样的路由。

    更多关于路由的信息可以在这里找到:Rails Guides | Routing From The Outside In

    请检查上述更改是否删除了您的空用户参数。

    【讨论】:

    • 嘿@thirdsun 我发布了与相关控制器关联的路由。如果我的 URL 有点不合常规,我深表歉意。我没有接受过任何关于 Ruby on Rails 的正式培训,并且不了解许多常见的编码约定和最佳实践。
    • @ScottOBot 谢谢,我更新了我的答案。同样,我的猜测是不寻常的路线设计(如用户之前的 :id)引入了意外/奇怪的参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 2011-01-23
    • 2017-01-15
    • 1970-01-01
    相关资源
    最近更新 更多