Использование флажков для фильтрации записей - PullRequest
5 голосов
/ 02 февраля 2011

Я пытаюсь выучить рельсы с нуля программирования, и у меня есть приложение, которое я пытаюсь сделать.С большой помощью от людей здесь у меня есть индексная страница мест, которые фильтруются, к какой области они принадлежат через выпадающее меню.Я хотел бы иметь возможность иметь тот же эффект, но с использованием флажков, а также возможность выбрать несколько областей для добавления в фильтр.Это то, что у меня есть:

Модель:

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 голосов
/ 02 февраля 2011

Я не знаю точно, что является причиной вашей ошибки, но я могу сказать вам, что помощник check_box_tag работает не так, как вы ожидаете. Из документации она определяется следующим образом:

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

Так что повторный вызов check_box_tag("area", "name") просто даст вам <input id="area" name="area" type="checkbox" value="name" /> несколько раз. Обратите внимание, что атрибут «значение» (то есть значение, которое отправляется на ваш сервер при отправке этой формы) всегда является «именем», а не тем, что вы хотите!

Вместо этого попробуйте следующее:

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

Вещи, которые я изменил:

  1. Я использовал Area.all вместо Area.find(:all) - я сделал это по косметическим причинам, но в ответе DanneManne утверждается, что он устарел в Rails 3 (я бы не знал - я все еще на 2.3.8).
  2. Я использовал идентификатор области вместо ее имени в поле значения; всегда полезно искать информацию по идентификатору, если вы можете - идентификаторы являются целыми числами и сравниваются быстрее, чем строки, и в вашей базе данных всегда будет индекс для столбца идентификатора для сверхбыстрых поисков.
  3. И последний, но способ, что наиболее важно Я добавил [] после имени ввода. Это позволяет Rails собирать все значения, представленные с этим именем, в массив, а не просто брать последнее. Смотрите ниже:

Бросив URL ...

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

... в приложении Rails выдает хэш параметров ...

{: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]})

Просто убедитесь, что у вас есть действительный массив идентификаторов областей, прежде чем вызывать этот искатель - если вы этого не сделаете, ваш хэш условий оценивается как {: area_id => nil}, а Rails найдет вам все места, которые не У меня есть area_id - вероятно, нет, и определенно не то, что вы хотите.

Надеюсь, это поможет!

0 голосов
/ 02 февраля 2011

При вызове Area.find вы указываете аргумент: все. Этот синтаксис устарел в Rails 3, который, я полагаю, вы используете. Все предыдущие использования find (: all, ...) или find (: first, ...) и т. Д. Больше не могут быть использованы. Вместо этого вы должны использовать его, как вы в первой форме: Area.all (...)

Как примечание, похоже, что аргументы check_box_tag могут быть неверными. Я думаю, вы должны отправить .name вместо "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>
...