【问题标题】:How to deserialize params received as JSON string in controller?如何反序列化在控制器中作为 JSON 字符串接收的参数?
【发布时间】:2019-03-19 02:26:31
【问题描述】:

我正在使用 Rails 编写一个接收 JSON 作为其参数的控制器,然后使用 Rspec 请求规范对其进行测试。

控制器:

class API::UserController < ApplicationController
  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to @user
    else
      render json: { errors: @user.errors.full_messages }, status: :unprocessable_entity
    end

  private

  def user_params
    params.require(:user).permit(:username, :email, :name, :password_digest)
  end
end

规格:

RSpec.describe "User creation", type: :request do
  def create_user_request
    params = { user: build(:user), format: :json }
    post api_users_path, params: params.to_json
  end

  it 'should create a new user' do
    expect { create_user_request }.to change { User.count }.by(1)
end

但这失败了:

     Failure/Error: params.require(:user).permit(:username, :name, :email, :password_digest)

     ActionController::ParameterMissing:
       param is missing or the value is empty: user

我认为问题在于控制器中的params 是作为字符串的序列化 JSON 对象。如果我在规范中将params: params.to_json 替换为params: params,则user 参数将变为字符串"#&lt;User:0x.....&gt;"

如何让规范和控制器配合得很好?

【问题讨论】:

    标签: ruby-on-rails json


    【解决方案1】:

    我认为第一个问题是您需要将模型转换为哈希(而不是对其进行字符串化)。最简单的方法是使用.attributes,即

    build(:user).attributes
    

    我也不确定您是否应该将format: :json 作为参数的一部分传递,但我认为这取决于您使用的rails、rspec 等版本,但对于rails 4,对我有用的是

    post api_users_path, user: build(:user).attributes, format: :json
    

    【讨论】:

    • 谢谢,不敢相信我在这个问题上花了这么多时间!
    猜你喜欢
    • 2016-07-29
    • 2016-08-31
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    • 2018-05-30
    相关资源
    最近更新 更多