2009-02-20 5 views
1

Les modèles projet et catégorie sont dans une relation has_and_belongs_to_many. Le partiel vu ci-dessous est utilisé sur différentes vues pour afficher un menu déroulant avec toutes les catégories disponibles. Les projets dans la liste sous le menu déroulant sont affichés en fonction du choix effectué par l'utilisateur dans le menu déroulant. Outre les autres catégories, il existe une catégorie nommée "Tout" dont chaque projet est membre. C'est aussi la première entrée dans la catégorie-db-table, car elle a été insérée lors du chargement des migrations dans la base de données.Utilisation de helper d'affichage collection_select pour les objets dans une relation HABTM

Pour l'instant, il n'y a pas d'erreur, mais quelle que soit la catégorie que je choisis, la page "Tout" est rechargée.

Une idée de ce que j'ai besoin de changer dans le code mentionné ci-dessous pour le faire fonctionner comme je le veux? Merci de votre aide!

partielle avec menu déroulant et projet liste

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

Logoutput après avoir choisi la catégorie avec id 2 sur le menu déroulant

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

Catégorie Modèle

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

Catégories contrôleur

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 

Modèle Projet

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

Projets Contrôleur

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 

partie des 'routes râteau' Sortie

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

Répondre

0

Merci Andrew, mais je résolu moi-même de cette façon:

Je me suis débarrassé de collection_select, changé en sélectionnez, ajouté l'action de filtrage (avec l'itinéraire correspondant dans config/routes.rb) et maintenant tout fonctionne comme prévu.

... J'essaie d'obtenir un observateur sur le menu de sélection, qui soumet sa valeur à l'action de filtre dès que l'utilisateur change la sélection dans le menu de sélection, mais c'est une autre histoire. ;-)

Nouveau partiel avec menu déroulant et projet liste

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

contrôleur Nouvelles catégories

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

vous passez un paramètre appelé :category_ids, mais vous n'êtes pas accès à ce partout.

form_for category_url(:id) 

Cela soumettre votre formulaire au chemin /categories/1 ou tout autre identifiant que vous regardez actuellement. Vous êtes alors en utilisant que:id pour trouver vos projets de catégorie:

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

Vous êtes juste montrer les mêmes encore. Parce que c'est une forme, vous soumettez une requête avec le paramètre: category_ids:

POST /categories/1?category_ids=2 

Vous pouvez simplement changer votre Category.find d'utiliser l'autre paramètre à la place. Mais, normalement pour afficher la catégorie 2, vous utiliserez simplement l'URL /categories/2, où 2 est votre paramètre: id.Vous avez deux identifiants dans ce chemin, et vous devez décider comment vous voulez résoudre cela.

Une option est d'utiliser le categories_path pour l'action de forme, et changer le collection_select: paramètre category_ids juste :id:

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

Mais si vous êtes une simple liste des projets, je propose cette logique dans la contrôleur de projets (action d'index), de sorte que vos URL ressemblerait à ceci:

/projects?category_id=2` # from the form 
/categories/2/projects # from a link 
Questions connexes