【问题标题】:RSpec doesn't return Hash field to ControllerRSpec 不会将哈希字段返回给控制器
【发布时间】:2015-01-09 05:17:55
【问题描述】:

所以我在我的 Rails API 中运行#create 测试,但不知何故,Factory 中的一个字段是 Hash 并没有到达控制器以进行 INSERT。

工厂

    factory :child do
        id 5
        type "type1"
        vars { var1: 1, var2: 2 }
        values { value1: 1, value2: 2 }
    end

测试

    it "creates child with associated id" do
        Rails::logger.info "Testing CREATE"
        child = FactoryGirl.build(:child).attributes
        Rails::logger.info "INITIAL:"
        Rails::logger.info child
        post :create, :parent => @parent_id, :child => child
        expect(response).to have_http_status(201)
    end

控制器动作

def create
    @parent = Parent.find(params[:parent_id])
    @child = @parent.childs.build(child_params)

    if @child.save
      render json: @child, status: 201
    else
      render json: { error: "404: Not Found" }.to_json, status: 404 #just to know, this error will be changed
    end
end

(...) some code here

def child_params
  params.require(:child).permit(:id, :type, :parent_id) #here I've also tried to include :vars, :value unsuccessfully
end

结果

D, [2015-01-08T20:02:19.016182 #76314] DEBUG -- :   SQL (0.9ms)  
INSERT INTO "childs" ("id", "type", "parent_id", "created_at", "updated_at") 
VALUES ($1, $2, $3, $4, $5) RETURNING "id"  
[["id", 1], ["type", "type1"], ["parent_id", 1], ["created_at", "2015-01-08 20:02:19.010801"], ["updated_at", "2015-01-08 20:02:19.010801"]]

如您所见,控制器不会读取变量和值的哈希值。 RSpec 测试可以很好地读取它们:

I, [2015-01-08T20:02:18.989104 #76314]  INFO -- : 
{"id"=>1, "type"=>"type1", "vars"=>{"var1"=>"1", "var2"=>"2"}, "values"=>{"value1"=>"1", "value2"=>"2"}, "created_at"=>nil, "updated_at"=>nil, "parent_id"=>nil}

我错过了什么吗?

【问题讨论】:

  • child 的定义是怎样的?为什么复数很时髦?
  • 它们是示例名称(模型的子名称和控制器的子名称,不要介意它们)。抱歉,按照孩子的定义,你是什么意思?
  • 我印象深刻的是它不会崩溃,当你在工厂中使用 { } 时它被视为一个块,所以你应该做类似vars { {va1: 'aaa', var2: 'sth'} }
  • @Swistaku 是的,我忘了指出这一点。这里好像真的没关系,我试过 vars {}, vars {{ x: y }} 和 vars { { x: y } } 结果总是一样的。
  • 强参数是否允许这样做(child_params 方法)?你能展示一下这个方法吗?

标签: ruby-on-rails hash rspec


【解决方案1】:

目前 strong_params 不允许(AFAIK 和 according to this)允许内部包含未知键的哈希,因此您需要在强参数中执行类似操作,如果您知道键

def child_params
  params.require(:sth).permit(:id, :type, :parent_id, vars: [:var1, :var2], values: [:value1, :value2]) 
end

或者干脆做

def child_params
  params.require(:sth).permit!
end

这是从我的控制台直播的

[7] pry(#<Admin::SampleController>)> params.require(:sth).permit(:type, vars: [:var1, :var2])
Unpermitted parameters: id, values, created_at, updated_at, parent_id
=> {"type"=>"type1", "vars"=>{"var1"=>"1", "var2"=>"2"}}
[8] pry(#<Admin::SampleController>)> params.require(:sth).permit(:type, vars: [[]])
Unpermitted parameters: var1, var2
Unpermitted parameters: id, values, created_at, updated_at, parent_id
=> {"type"=>"type1", "vars"=>{}}
[9] pry(#<Admin::SampleController>)> params.require(:sth).permit!
=> {"id"=>1,
 "type"=>"type1",
 "vars"=>{"var1"=>"1", "var2"=>"2"},
 "values"=>{"value1"=>"1", "value2"=>"2"},
 "created_at"=>nil,
 "updated_at"=>nil,
 "parent_id"=>nil}

【讨论】:

  • 哇。非常非常感谢您的努力!我一直在为此苦苦挣扎,这就是解决方案。 (很抱歉没有给你的答案投票,还没有足够的代表)
  • 关于我提到的问题,也有一些巧妙的想法如何解决这个问题:)
  • 我一定会看看的。再次感谢:)
  • 顺便说一句,查看selleo-controller_tests gem 进行控制器测试;)
  • 这似乎是个不错的宝石。当我完成这个项目时,我一定会尝试一下 :) 从现在开始,可能会将它包含在我的工作中。
猜你喜欢
  • 1970-01-01
  • 2018-07-03
  • 2016-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多