为什么我无法访问 flash 的内容,因为它是哈希?



根据Flash文档,我应该能够通过Flash传递字符串、数组或散列。字符串和数组可以正常工作,但哈希不起作用。

这是我代码的精简版(但仍然失败(:

Flash消息部分

# views/layouts/flash_messages.html.haml
- flash.each do |type, content|
- message = content if content.class == String
- message, detail = content if content.class == Array
- message, detail = content[:message], content[:detail] if content.class == Hash
- if message || detail
.alert
%h3= message if message.present?
%p= detail if detail.present?

家庭控制器

class HomeController < ApplicationController
def index
end
def test_string
redirect_to root_url, alert: 'Plain string works'
end
def test_array
redirect_to root_url, alert: ['Array works', 'Tested with 0, 1, 2 or more items without problems']
end
def test_hash
redirect_to root_url, alert: {message: 'Hash not working :(', detail: 'Even though I think it should'}
end
end

在散列的情况下,问题似乎出在赋值行上,键是存在的,但对于散列,methoddetail总是为零。但当我在控制台中尝试相同的代码时,它工作得很好。。。

IRB

irb> content = { message: 'This hash works...', detail: '...as expected' }
=> {:message=>"This hash works...", :detail=>"...as expected"}
irb> message, detail = content[:message], content[:detail] if content.class == Hash
=> [ 'This hash works...', '...as expected' ]
irb> message
=> 'This hash works...'
irb> detail
=> '...as expected'

仔细检查发现,虽然键确实设置好了,但它们已经从符号转换为字符串。

为了解决这个问题,我不得不将控制器的第4行从符号改为字符串:

- message, detail = content[:message], content[:detail] if content.class == Hash
- message, detail = content['message'], content['detail'] if content.class == Hash

如果我理解正确的话,这是flash存储在会话中,会话对象作为JSON对象存储在cookie中的结果。JSON不支持符号键。

作为一个实验,我尝试设置匹配的字符串和符号键。如果您尝试在一个赋值中同时执行这两个操作,Ruby将获取第一个键和第二个值(带有警告(:

irb> content = { message: 'Symbol key first', 'message': 'String key second' }
=> warning: key :message is duplicated and overwritten on line X
=> {:message=>"String key second"}

但是,如果你故意在传递给flash的散列中复制密钥,则最后定义的密钥为";获胜";(在我有限的测试中,但这是有意义的,因为哈希很可能是按插入顺序迭代的(:

symbol_first = {}
symbol_first[:message] = 'Symbol wins'
symbol_first['message'] = 'String wins'
flash[:alert] = symbol_first # 'String wins' is displayed
string_first = {}
string_first['message'] = 'String wins'
string_first[:message] = 'Symbol wins'
flash[:alert] = string_first # 'Symbol wins' is displayed

相关内容

最新更新