为什么我的控制器要求params散列重复嵌套?

时间:2018-03-21 15:31:17

标签: ruby-on-rails ruby rspec

我目前有以下情况:

ChallengeRequestsController #new - 创建ChallengeRequest以及需要 recpient_id 的另一个模型。

def create
  @challenge_request = ChallengeRequest.new(challenge_params)

  recipient = User.find(params.require(:recipient_id))

  # Rest of method redacted.
end

def challenge_params
  params.require(:challenge_request).permit(:action)
end

使用此控制器,我进行了如下RSpec测试:

RSpec.describe ChallengeRequestsController, type: :controller do
  describe "POST #create" do

    context "with valid challenge request" do
      let(:valid_challenge_request) { build(:challenge_request) }

      context "with non-exisistent recpient id" do
        it "throws an error" do
          expect{
            post :create, :params => {
              :challenge_request => {
                :challenge_request => valid_challenge_request
              },
              :recipient_id => 10000
            }
          }.to raise_error ActiveRecord::RecordNotFound
        end
      end

    end
  end
end

仅供参考,这是工厂:

FactoryGirl.define do
  factory :challenge_request do
    action { Faker::LeagueOfLegends.champion }
  end
end

所有这些代码都有效,测试通过了,我的问题是如何以一种我不需要在请求中使用丑陋嵌套的方式重构它?

:challenge_request => {
  :challenge_request => valid_challenge_request
}

在没有此嵌套的情况下发布请求时:

post :create, :params => {
  :challenge_request => valid_challenge_request,
  :recipient_id => 10000
}

当ChallengeRequestController收到请求时,challenge_request为空。

1 个答案:

答案 0 :(得分:1)

如果您将valid_challenge_request更改为属性的哈希值而不是模型本身,则可能会有效。

let(:valid_challenge_request) { FactoryBot.attributes_for(:challenge_request) }

你试图将模型的一个实例作为参数发送到控制器,而某些东西正在做某事(我无法找到对模型做什么)试图将其强制转换成浏览器可能会发送控制器。该转换将模型转换为空字符串,该字符串不是 present或值false ,因此导致require抛出ParameterMissing }