[英]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">▾</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]
访问:all
, post_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
是一个数组,同时包含key
和value
。
采用:
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">▾</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.