Использование помощника вида collection_select для объектов в отношении HABTM - PullRequest
1 голос
/ 20 февраля 2009

Модели проекта и категории находятся в отношении has_and_belongs_to_many. Часть, показанная ниже, используется в разных представлениях, чтобы показать выпадающее меню со всеми доступными категориями. Проекты в списке под раскрывающимся меню отображаются в соответствии с выбором, который пользователь сделал в раскрывающемся меню.

Помимо других категорий, есть категория «Все», членом которой является каждый проект. Это также первая запись в category-db-table, потому что она была вставлена ​​во время загрузки миграций в базу данных.

Сейчас ошибки нет, но независимо от того, какую категорию я выбрал, она перезагружает страницу с категорией «Все».

Есть идеи, что мне нужно изменить в коде, упомянутом ниже, чтобы он работал так, как я хочу? Спасибо за вашу помощь!

Частично с выпадающим меню и списком проектов

<!-- category dropdown -->
<% form_for category_url(:id), :html => {:method => :get} do |f| %>
    <label>Categories</label>
     <%= f.collection_select(:category_ids , Category.find(:all), :id , :name) %>
     <%= f.submit "Show" %>
<% end %>

<!-- project list -->
<ul class="projectlist">
  <% @projects.each do |_project| %>
    <li>
      <%= link_to(_project.name, _project) %>
    </li>
  <% end %>
</ul>

Выход из системы после выбора категории с идентификатором 2 в раскрывающемся меню

Processing ProjectsController#index (for 127.0.0.1 at 2009-02-20 17:26:10) [GET]
  Parameters: {"commit"=>"Show", "http://localhost:3000/categories/id"=>{"category_ids"=>"2"}}

Категория Модель

class Category < ActiveRecord::Base
  has_and_belongs_to_many :projects, :join_table => "categories_projects"
end

Категории Контроллер

class CategoriesController < ApplicationController
  def show
    @projects = Category.find(params[:id]).projects.find(:all)

    respond_to do |format|
      format.html # show.html.erb
    end
  end
end

Модель проекта

class Project < ActiveRecord::Base
  has_and_belongs_to_many :categories, :join_table => "categories_projects"
end

Контроллер проектов

class ProjectsController < ApplicationController
  def show
    @projects = Project.find(:all)
    @project = Project.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
    end
  end

  def index
    @projects = Project.find(:all)

    respond_to do |format|
      format.html # index.html.erb
    end
  end
end

часть вывода «Рейк-маршруты»

category GET    /categories/:id  {:controller=>"categories", :action=>"show"}

Ответы [ 2 ]

0 голосов
/ 22 февраля 2009

Спасибо, Андрей, но я сам решил это так:

Я избавился от collection_select , изменил на select , добавил действие фильтра (с соответствующим маршрутом в config / rout.rb), и теперь все работает, как я ожидал.

... Я пытаюсь вызвать наблюдателя в меню выбора, который передает его значение фильтрующему действию, как только пользователь меняет выбор в меню выбора, но это уже другая история. ; -)

Новый фрагмент с выпадающим меню и списком проектов

    <% form_tag(filter_category_path(:id), :method => :post, :class => 'categories') do %>
       <label>Categories</label>
       <%= select_tag(:category, options_for_select(Category.all.map {|category| [category.name, category.id]}, @category.id)) %>
       <%= submit_tag "Go" %>
     <% end %>

   <ul class="projects">
     <% @projects.each do |_project| %>
       <li>
         <%= link_to(_project.name, _project) %>
       </li>
     <% end %>
   </ul>

Контроллер новых категорий

class CategoriesController < ApplicationController
  def show
    @category = Category.find(params[:id])
    @projects = @category.projects.find(:all)

    respond_to do |format|
      format.html 
    end
  end

  def filter
    @category = Category.find(params[:category])
    @projects = @category.projects.find(:all)

    respond_to do |format|
      format.html
    end    
  end
end
0 голосов
/ 21 февраля 2009

Вы передаете параметр с именем :category_ids, но ни к чему не обращаетесь.

form_for category_url(:id)

Это отправит вашу форму на путь /categories/1 или любой другой идентификатор, который вы просматриваете в настоящее время. Затем вы используете что :id для поиска проектов вашей категории:

@projects = Category.find(params[:id]).projects.find(:all)

То есть вы снова показываете те же самые. Поскольку это форма, вы отправляете запрос с параметром: category_ids:

POST /categories/1?category_ids=2

Вы можете просто изменить ваш Category.find, чтобы использовать другой параметр. Но обычно для просмотра категории 2 вы просто используете url /categories/2, где 2 - ваш параметр: id. У вас есть два идентификатора на этом пути, и вы должны решить, как вы хотите разрешить это.

Один из вариантов - использовать categories_path для действия формы и изменить параметр collection_select: category_ids на :id:

/categories?id=2  # from the form
/categories/2     # from a link

Но если вы просто перечисляете проекты, я бы переместил эту логику в контроллер проектов (действие index), чтобы ваши URL выглядели так:

/projects?category_id=2` # from the form
/categories/2/projects   # from a link
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...