如何反序列化控制器中作为JSON字符串接收的参数?

时间:2019-03-19 02:26:31

标签: ruby-on-rails json

我正在使用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参数将变成字符串"#<User:0x.....>"

我如何使规范和控制器完美配合?

1 个答案:

答案 0 :(得分:1)

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

build(:user).attributes

我也不确定您是否应该将format: :json作为参数的一部分进行传递,但是我认为这取决于您使用的是哪个版本的rails,rspec等,但是对于rails 4来说,什么才适用我是

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