2017-08-30 196 views
1

我在我的rspec测试中遇到了错误天数。后来我发现,问题是用符号代替串字符串vs符号rails

user_response = JSON.parse(response.body, symbilize_names: true) 
expect(user_response[:email]).to eql(@user.email) 

因为user_response[:email]回报nil因为某些原因

但是,当我将其更改为user_responce['email']测试通过

上面的代码总是失败

调试与byebug检查USER_RESPONSE的价值

(byebyg) user_response 
{"id"=>1, "email"=>"[email protected]", "created_at"=>"2017-08-30T14:22:43.597Z", "updated_at"=>"2017-08-30T14:22:43.597Z"} 

什么在上面的情况下使用符号和字符串之间的区别?

+8

你有一个错字:'symbilize_names'应该是'symbolize_names' – Stefan

+1

(因此'JSON.parse'应该引发一个'ArgumentError',但这是一个不同的故事) – Stefan

回答

5

在Ruby中使用哈希时,任何对象如字符串或符号都可以用作关键字。但是,:email"email"是不同的对象,因此要查找对象,必须使用与用于存储该值的对象相同的对象。

您可能会困惑的是Rails在某些地方使用HashWithIndifferentAccess。这是一个自定义散列,其中键:foo"foo"被认为是相同的。这使您可以使用例如params[:user]params["user"]可互换,但这不是一般情况。

由于Stefan发现,为什么丝线被用于在解析JSON对象的键的原因是刚下来在选择一个小错字:symbilize_names它应该是symbolize_names

2

符号和字符串只是不同类型的对象。与'5'5不同。他们表面上看似看起来相似,但实际上它们并没有关系。

在上面的情况下使用符号和字符串有什么区别?

在你的情况下,你的数据结构包含字符串键并且不包含符号键。就那么简单。

3

这实际上与符号或字符串本身无关。你有一个散列。该散列值包含密钥'email'的值。它不包含键值'foobar'42:hello[1, 2, 3]:email的值。 Ergo,如果你问它其中的一个值,你会得到默认值,默认值为nil

这不是关于符号或字符串。您只需要询问散列值是否存在密钥。在散列中没有键:email,如果您获得默认值。