繁体   English   中英

如何通过密钥访问哈希

[英]How to access a hash by key

我正在尝试构建一个Rails帮助器,它将创建一个嵌套的下拉菜单,其中包含链接,其中最上面的是“ All”或当前参数,并且该下拉菜单包含其他选项(如果有的话),但不包括当前参数。

例如,如果我没有post_type参数,则会看到:

<ul>
    <li><a href="">All</a>
        <ul>
            <li><a href="">Discussions</a></li>
            <li><a href="">Snaps</a></li>
            <li><a href="">Code</a></li>
            <li><a href="">Links</a></li>
        </ul>
    </li>
</ul>

但是,如果我有一个“讨论”的post_type参数,那么我会看到:

<ul>
    <li><a href="">Discussions</a>
        <ul>
            <li><a href="">All</a></li>
            <li><a href="">Snaps</a></li>
            <li><a href="">Code</a></li>
            <li><a href="">Links</a></li>
        </ul>
    </li>
</ul>

我认为我有:

<ul class="filter-menu">
  <li>
    <%= current_post_type(params) %>
    <ul class="filter-menu__drop-down">
      <%= list_post_types(params) %>
    </ul>
  </li>
</ul>

在我的助手中,我有:

module PostsHelper

  def post_types
    @post_types = {
        :all => {
            :text => 'All post types',
            :icon => 'icon-file-text2',
            :post_type => nil}
    }, {
        :discussions => {
            :text => 'Discussions',
            :icon => 'icon-bubbles2',
            :post_type => 'discussions'}
    }, {
        :snaps => {
            :text => 'Snaps',
            :icon => 'icon-images',
            :post_type => 'snaps'}
    }, {
        :code => {
            :text => 'Code',
            :icon => 'icon-embed2',
            :post_type => 'code'}
    }, {
        :links => {
            :text => 'Links',
            :icon => 'icon-link',
            :post_type => 'links'}
    }
  end

  def post_type_text(icon, text, drop_down = false)
    raw('<i class="' + icon + '"></i> ' + text + (drop_down ? ' <span class="chevron">&#9662;</span>' : ''))
  end

  def post_type_path(post_type)
    posts_path(:filter => params[:filter], :time => params[:time], :post_type => post_type)
  end

  def current_post_type(params)
    if params[:post_type].present? # todo: check matches above
      post_type = params[:post_type].downcase
      link_to post_type_text(post_types[post_type][:icon], post_types[post_type][:text], true), post_type_path(post_types[post_type][:post_type])
    else
      link_to post_type_text(post_types[:all][:icon], post_types[:all][:text], true), post_type_path(post_types[:all][:post_type])
    end
  end

  def list_post_types(params)
    post_types.each do |post_type| # todo: exclude current post_type
      link_to post_type_text(post_types[post_type][:icon], post_types[post_type][:text]), post_type_path(post_types[post_type][:post_type])
    end
  end

end

我如何访问哈希? 我得到一个错误

no implicit conversion of Symbol into Integer

在做post_types[:all]

我认为这是因为post_types返回了一个哈希数组,在这里我想要的是可以通过键名访问的post_types

我可以通过post_types[0][:all][:icon]访问:allpost_types[0][:all][:icon]不适用于我的其他哈希,因为我想通过post_types[post_type][:icon]访问它们,其中post_type是名称我尝试访问的post_type键。

首先,声明一个哈希而不是一个数组:

@post_types ||= {
        :all => {
            :text => 'All post types',
            :icon => 'icon-file-text2',
            :post_type => nil},
        :discussions => {
            :text => 'Discussions',
            :icon => 'icon-bubbles2',
            :post_type => 'discussions'},
        :snaps => {
            :text => 'Snaps',
            :icon => 'icon-images',
            :post_type => 'snaps'},
        :code => {
            :text => 'Code',
            :icon => 'icon-embed2',
            :post_type => 'code'},
        :links => {
            :text => 'Links',
            :icon => 'icon-link',
            :post_type => 'links'}
    }

问题在这里:

post_types.each do |post_type| # todo: exclude current post_type
  link_to post_type_text(post_types[post_type] ...

您已经在遍历哈希,这里的post_type是一个数组,同时包含keyvalue

采用:

post_types.each do |k, v| # todo: exclude current post_type
  link_to post_type_text(v[:icon] ...

要了解发生了什么:

post_types.each do |post_type| # todo: exclude current post_type
  puts post_type.inspect

另外,sidenote:仅实例化实例变量一次:

def post_types
  #           ⇓⇓⇓ HERE
  @post_types ||= {...}

这最终解决了我的问题。

非常感谢mudasobwa的回答,我已接受了我的回答,但我想与任何遇到此问题的人分享最终代码。

module PostsHelper

  def post_types
    @post_types ||= {
        :all => {
            :text => 'All post types',
            :icon => 'icon-file-text2',
            :post_type => nil},
        :discussions => {
            :text => 'Discussions',
            :icon => 'icon-bubbles2',
            :post_type => 'discussions'},
        :snaps => {
            :text => 'Snaps',
            :icon => 'icon-images',
            :post_type => 'snaps'},
        :code => {
            :text => 'Code',
            :icon => 'icon-embed2',
            :post_type => 'code'},
        :links => {
            :text => 'Links',
            :icon => 'icon-link',
            :post_type => 'links'}
    }
  end

  def post_type_text(icon, text, drop_down = false)
    raw('<i class="' + icon + '"></i> ' + text + (drop_down ? ' <span class="chevron">&#9662;</span>' : ''))
  end

  def post_type_path(post_type)
    posts_path(:filter => params[:filter], :time => params[:time], :post_type => post_type)
  end

  def current_post_type(params)
    post_type = params[:post_type].present? ? params[:post_type].downcase.to_sym : :all
    if post_types.key?(post_type)
      link_to post_type_text(post_types[post_type][:icon], post_types[post_type][:text], true), post_type_path(post_types[post_type][:post_type])
    else
      link_to post_type_text(post_types[:all][:icon], post_types[:all][:text], true), post_type_path(post_types[:all][:post_type])
    end
  end

  def list_post_types(params)
    html = ''
    post_type = params[:post_type].present? ? params[:post_type].downcase.to_sym : :all
    exclude_all = post_types.key?(post_type) ? false : true
    post_types.each do |k, v|
      if exclude_all && k == :all
      else
        html += "<li>#{link_to post_type_text(v[:icon], v[:text]), post_type_path(v[:post_type])}</li>" if k != post_type
      end
    end
    html.html_safe
  end

end

暂无
暂无

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

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