2010-11-12 5 views
0

Dans mon fichier « routes.rb » J'ai la ligne suivante:Comment puis-je créer une ressource qui est le sous-ensemble d'une ressource existante

resource :users 

qui me donne un tas de routes nommées pour accéder à mon modèle d'utilisateur d'une manière RESTful.

Maintenant, j'ai fait quelques ajouts au modèle de l'utilisateur, y compris la création d'une classe spéciale d'utilisateur. Ceux-ci sont toujours stockés dans le modèle User mais il existe un indicateur "spécial" dans la base de données qui les identifie comme spéciaux.

Alors, est-il possible de créer des ressources special_users? Par exemple, j'aimerais que "special_users_path" devienne un chemin nommé "/ special_users" qui renverra un index des utilisateurs spéciaux seulement lorsque vous effectuerez un GET sur l'URL.

Existe-t-il un moyen de le faire?

Répondre

0

Dans le routage Rails, une 'ressource' fait référence aux 7 itinéraires standards qui sont créés pour les ressources RESTful: index, show, new, create, edit, update et destroy. Normalement, cela suffit, mais parfois vous pourriez vouloir créer une autre action.

Dans le modèle, vous voulez créer un scope qui retourne uniquement les utilisateurs spéciaux:

class User < ActiveRecord::Base 
    scope :special, where(:special => true) 
end 

Du côté du contrôleur, il y a deux façons d'aller à ce sujet. Ce que vous proposez est la création d'une action supplémentaire:

match "https://stackoverflow.com/users/special" => "users#special" 
resource :users 

Dans le contrôleur, votre action spéciale retournerait la portée que vous venez de créer:

class UsersController < ApplicationController 
    def special 
    @users = User.special 
    end 
end 

Cela va faire ce que vous demandez, mais je suggérerait de ne pas le faire de cette façon. Que faire si vous ajoutez plus tard d'autres drapeaux que vous souhaitez rechercher? Que faire si vous voulez effectuer une recherche par plusieurs drapeaux? Cette solution n'est pas assez flexible pour cela. Au lieu de cela, garder les routes comme ils sont:

resource :users 

et il suffit d'ajouter une ligne supplémentaire à votre contrôleur:

class UsersController < ApplicationController 
    def index 
    @users = User.all 
    @users = @users.special if params[:special] 
    end 
end 

et maintenant, lorsque vous souhaitez afficher les utilisateurs particuliers, directement simplement à l'utilisateur de /users?special=true

Cette approche est beaucoup plus à l'épreuve du futur, IMO.

(Cette réponse est basée sur Rails-3. Si vous utilisez encore 2.3 laissez-moi savoir)

+0

Dans votre premier exemple, le lambda n'est pas nécessaire. Cela fera l'affaire: scope: special, where (special: true) – noodl

+0

@noodl Merci, encore en train de vous habituer à arel. –

+0

Merci! Belle explication et j'apprécie vraiment que vous allez à la peine de montrer une autre méthode ainsi que le cas trivial. – spinlock

0

Vous pouvez définir les special_users comme une ressource:

resource :special_users 

Si vous devez pointer vers un contrôleur spécial, vous pouvez spécifier avec:

resource :special_users, :controller => :users 

Mais Je voudrais vraiment vous suggérer de ne pas créer un autre contrôleur pour récupérer un type d'utilisateur, mais en utilisant un param pour les obtenir:

class UsersController < ApplicationController 
    def index 
    users = case params[:type].to_s 
       when "special" 
       User.special_users # Using named scopes 
       else 
       User.all 
      end 
    end 
end 

Lorsque vous utilisez le users_path pour appeler les utilisateurs spéciaux:

users_path(:type => :special) 
Questions connexes