简体   繁体   English

为什么我不能访问 hash 的 flash 的内容?

[英]Why can't I access contents of flash when it's a hash?

According to the Flash documentation , I should be able to pass strings, arrays or hashes through Flash.根据Flash 文档,我应该能够通过 Flash 传递字符串、arrays 或散列。 Strings and arrays work fine but hashes aren't working.字符串和 arrays 工作正常,但哈希不起作用。

Here's a stripped down (but still failing) version of my code:这是我的代码的精简版(但仍然失败):

Flash messages partial 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?

Home controller controller

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

The problem seems to be with the assignment line in the case of the hash, the keys are present but method and detail always end up nil for hashes.在 hash 的情况下,问题似乎出在分配行上,密钥存在,但methoddetail对于哈希值总是为零。 But when I try the same code in the console it works fine...但是当我在控制台中尝试相同的代码时,它工作正常......

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'

Closer inspection revealed that, while the keys were indeed set, they'd been converted from symbols to strings.仔细检查发现,虽然确实设置了键,但它们已从符号转换为字符串。

To fix this I had to change line 4 of the controller from symbols to strings:为了解决这个问题,我必须将 controller 的第 4 行从符号更改为字符串:

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

If I understand correctly , this is a result of flashes being stored in the session and the session object being stored in cookies as JSON objects. If I understand correctly , this is a result of flashes being stored in the session and the session object being stored in cookies as JSON objects. JSON doesn't support symbolised keys. JSON 不支持符号化键。

As an experiment I tried setting matching string and symbol keys.作为一个实验,我尝试设置匹配的字符串和符号键。 If you try doing both in one assignment, Ruby takes the first key and the second value (with a warning):如果您尝试在一个作业中同时执行这两项操作,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"}

But if you deliberately duplicate the keys in a hash passed to flash, whichever one is defined last "wins" (in my limited testing, but it makes sense given hashes are most likely iterated in insertion order ):但是,如果您故意复制传递给 flash 的 hash 中的键,则无论最后定义的哪个“获胜”(在我有限的测试中,但考虑到哈希很可能以插入顺序迭代,这是有道理的):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM