我正在尝试构建一个Rails助手,它将创建一个嵌套的下拉菜单,其中包含最顶层的链接,#34; 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
参与讨论&#39;然后我会看到:
<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
正在返回一个散列数组,其中我想要的是一个可通过键名访问的散列哈希。
我可以通过:all
访问post_types[0][:all][:icon]
,但这对我的其他哈希不起作用,因为我想通过post_types[post_type][:icon]
访问post_type
我试图访问的post_type
密钥的名称。
答案 0 :(得分:1)
首先,声明一个哈希而不是一个数组:
@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
另外,旁注:仅实例化实例变量一次:
def post_types
# ⇓⇓⇓ HERE
@post_types ||= {...}
答案 1 :(得分:0)
这就是我最终解决了我的问题。
非常感谢 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