2017-01-13 8 views
0

リンクのネストされたドロップダウンメニューを作成するRailsヘルパーを作成しようとしています。リンクのトップは「すべて」または現在のパラメータです。ドロップダウンには、現在のパラメータがある場合はそれを返します。キーでハッシュにアクセスする方法

<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のparamを持っていたならば、私が見るであろう:私の見解では

<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> 

を私が見るであろう何post_typeのparamを持っていない場合、例えば

、私は持っています:

<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[0][:all][:icon]経由:allにアクセスすることができましたが、私はpost_typeは、私がアクセスしようとしていますpost_typeキーの名前ですpost_types[post_type][:icon]経由してアクセスしたいので、これは、私の他のハッシュのために動作しません。

答えて

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ここでは、配列は、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 

、追記:一度だけインスタンス変数をインスタンス化:

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

paramを使用して直接アクセスする方法はありますか?例えば'params [:post_type]'とそれからハッシュの配列にアクセスしますか? – Cameron

+0

私はこの質問を理解していません。 'post_type.each'の中に' puts post_type.inspect'や 'binding.pry'を直接使うと、必要なものすべてを手に入れることができます。 – mudasobwa

+0

さて、私はそのリストからキー名でハッシュを取得する必要があります。したがって、 'params [:post_type]'が 'discussion'であれば、' discussion: 'にアクセスしてその値にアクセスしたいので、そのリンクを作成することができます。 – Cameron

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">&#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 
+0

これは受け入れられた答えを意図していますか?そうでない場合は、完成したコードを示す回答を作成しないでください。それは人を混乱させ、SOが使用する形式を破ります。それが選択された答えである場合、SOはあなたがタイムアウト期間後にそれを選択することを可能にするでしょう。 –

関連する問題