2011-02-02 10 views
5

私はプログラミングの経験からレールを学び、アプリケーションを作成しようとしています。ここにいる人々の多くの助けを借りて、私は会場のインデックスページを持っています。これらのページは、ドロップダウンメニューを介してそれらが所属するエリアによってフィルタリング可能です。私は同じ効果を持つことができますが、チェックボックスを使用して、フィルタに追加する複数の領域を選択することもできるようにしたいと思います。これは私がこれまで持っているものです。チェックボックスを使用してレコードをフィルタリングする

モデル:

class Venue < ActiveRecord::Base 
    belongs_to :user 
    has_many :reviews 
    belongs_to :area 

    scope :north, where(:area_id => "2") 
    scope :west, where(:area_id => "3") 
    scope :south, where(:area_id => "4") 
end 

コントローラー:

def index 
    if (params[:area] && Area.all.collect(&:name).include?(params[:area][:name])) 
    @venues = Venue.send(params[:area][:name].downcase) 
    else 
    @venues = Venue.all 
    end 
end 

会場index.html.erb:

<div class="filter_options_container"> 

    <form class="filter_form", method="get"> 
    <%= select("area", "name", Area.all.collect(&:name), {:prompt => 'All Areas'}) %><br> 
    <input type="submit" value="Filter" /> 
    </form> 

    <br><br> 

    <form class="filter_form", method="get"> 
    <% Area.find(:all).each do |a| %> 
     <%= check_box_tag("area", "name") %> 
     <%= a.name %> 
    <% end %> 
    <input type="submit" value="Filter" /> 
    </form> 
</div> 

<div class="venue_partials_container"> 
    <%= render :partial => 'venue', :collection => @venues %> 
    <div class="clearall"></div> 
    <%= link_to 'add a new venue', new_venue_path, :class => "add_new_venue_button" %> 
</div> 

最初の形式(ドロップダウン)filter_options_containerで正常に動作しますが、チェックボックス(2番目の形式)が返されます "シンボルを整数に変換できません"私は何が間違っている/間違っているのですか?

ありがとうございました。

答えて

8

:ここ

は、私が作品を考えて修正された形でありますに。 the documentationから、それは次のように定義されています:

check_box_tag(name, value = "1", checked = false, options = {}) 

だから、繰り返しcheck_box_tag("area", "name")を呼び出すと、あなたに複数回与えます。 「value」属性(フォームが送信されたときにサーバーに送信される値)属性は、常に「名前」です。これはあなたが望むものではありません。

代わりに、次のことを試してください。

<% Area.all.each do |a| %> 
    <%= check_box_tag("areas[]", a.id) %> 
    <%=h a.name %> 
<% end %> 

私が変更したもの:

  1. 私はArea.allの代わりArea.find(:all)を使用 - 私は美容上の理由のためにそれをやったが、DanneManneの答えは、それは時代遅れだと主張しますin Rails 3(私は知りません - まだ2.3.8です)。
  2. 私は値フィールドにその名前の代わりにエリアのIDを使用しました。 IDが整数であり、文字列よりも速く比較することができれば、IDで物事を見るのは常に良いことです。また、素早く参照できるように、データベースのID列には常にインデックスがあります。
  3. 最後に、方法が最も重要です入力名の後に[]に投げました。これにより、最後のものを取るのではなく、この名前で提出されたすべての値を配列に集めることができます。

    {:a => 12} 
    

    に...あなたのparamsハッシュを与えるのRailsアプリで... ...

URLを投げる

/whatever?a=3&a=17&a=12 

を...しかしURL:下記を参照してください。 ...

/whatever?a[]=3&a[]=17&a[]=12 

は...あなたが望むものを与える:

{:a => [3, 17, 12]} 

そして、あなたは、あなたが興味を持っているすべてのarea_idsの配列を持っている場合、あなたはでワンライナーでそれらの領域の任意のあるすべての会場を得ることができます(偉大なRailsのではないですか?) :

filtered_venues = Venue.all(:conditions => {:area_id => params[:areas]}) 

ちょうどあなたがそのファインダーを呼び出す前に、エリアIDの有効な配列を持っていることを確認してください - あなたがいない場合、あなたの条件のハッシュと評価されます{:AREA_ID => nilを}、およびRails'llあなたを見つけますarea_idを持たないすべての会場 - おそらく何もなく、あなたが望むものではないでしょう。

希望すると便利です。

+0

鮮やかな答えがありがとうございました! – Dave

+0

@Dave Glad私は助けることができました! –

0

Area.findへの呼び出しでは、引数:allを指定します。この構文は、使用していると想定しているRails 3では非推奨です。 find(:all、...)やfind(:first、...)などの以前の使用法はすべて使用できなくなりました。代わりに、最初の形式であなたのように使用する必要があります:Area.all(...)

また、check_box_tag引数が間違っているように見えます。私はあなたが "名前"の代わりにa.nameを送るべきだと思います。私はあなたのエラーを引き起こしている内容を正確に把握していないが、私はヘルパーは、あなたがそれを期待する方法は動作していないことを伝えることができ

<form class="filter_form", method="get"> 
    <% Area.all.each do |a| %> 
    <%= check_box_tag("area", a.name) %> 
    <%= a.name %> 
    <% end %> 
    <input type="submit" value="Filter" /> 
</form> 
関連する問題