Routage imbriquée ressources dans Rails 3
J'ai un assez commun en cas de imbriqués les routes, je me sens comme, qui ressemble à quelque chose comme ceci (dans une sorte de pseudonotation):
'/:username/photos' => Show photos for User.find_by_username
'/photos' => Show photos for User.all
En un mot: j'ai les utilisateurs. Ils ont des photos. Je veux être en mesure de montrer leurs photos sur leur page. Je veux aussi être capable de montrer toutes les photos, indépendamment de l'utilisateur. J'aimerais garder mes itinéraires et Reposant en utilisant le haut- resource
méthodes se sent comme la bonne façon de le faire.
Option 1 pour le faire, c'est d'avoir PhotosController#index utiliser une condition pour vérifier les paramètres sont donnés et obtenir la liste de toutes les photos et la vue (différent d'un utilisateur de photos que pour toutes les photos). Il est même facile de route:
resources :photos, :only => [:index]
scope ':/username' do
resources :photos
end
Boom. Il avait semblent comme des Rails a été mis en place pour cela. Après les routes, cependant, les choses deviennent plus compliquées. Que la condition de retour dans le PhotosController#index action est juste et de plus en plus gonflée et est en train de faire un tas de delgation. Comme la demande augmente et le nombre de façons que je veux vous montrer des photos, il ne va qu'empirer.
Option 2 peut-être d'avoir un Utilisateur::PhotosController pour gérer les photos des utilisateurs, et un PhotosController pour gérer l'affichage de toutes les photos.
resources :photos, :only => [:index]
namespace :user, :path => '/:username' do
resources :photos
end
Qui génère les itinéraires suivants:
photos GET /photos(.:format) {:action=>"index", :controller=>"photos"}
user_photos GET /:username/photos(.:format) {:action=>"index", :controller=>"user/photos"}
POST /:username/photos(.:format) {:action=>"create", :controller=>"user/photos"}
new_user_photo GET /:username/photos/new(.:format) {:action=>"new", :controller=>"user/photos"}
edit_user_photo GET /:username/photos/:id/edit(.:format) {:action=>"edit", :controller=>"user/photos"}
user_photo GET /:username/photos/:id(.:format) {:action=>"show", :controller=>"user/photos"}
PUT /:username/photos/:id(.:format) {:action=>"update", :controller=>"user/photos"}
DELETE /:username/photos/:id(.:format) {:action=>"destroy", :controller=>"user/photos"}
Cela fonctionne assez bien, je pense, mais tout est en vertu d'un Utilisateur module et je crois que cela pourrait finir par causer des problèmes quand je l'intégrer avec d'autres choses.
Questions
- Quelqu'un a de l'expérience avec quelque chose comme cela?
- Quelqu'un peut partager une meilleure façon de gérer cela?
- Supplémentaires, des avantages et des inconvénients à considérer avec l'une de ces options?
Mise à jour: j'ai pris de l'avance la mise en œuvre de l'Option 2 car il se sent plus propre permettant de Rails logique au travail plutôt que de passer outre. Pour l'instant tout va bien, mais j'ai aussi besoin de renommer mon espace de noms à :users
et ajouter un :as => :user
pour l'empêcher de heurter avec mon User
modèle. J'ai également remplacé la to_param
méthode sur la User
modèle de retourner le nom d'utilisateur. Chemin aides fonctionnent encore de cette façon, aussi.
Je serais encore apprécions les commentaires sur cette méthode. Je fais les choses de la manière prévue, ou suis-je un mauvais usage de cette fonctionnalité?
- Vous pouvez demander ce que vous voulez, bien sûr, mais vous vous contredisez un peu en demandant de repos des routes et explicitement routes exigeantes comme /:nom d'utilisateur/des photos qui n'est certainement pas de tout repos. Je pense que la question est valable même pour vraiment Reposante routes, comme /utilisateurs/:user_id/photos et si la solution est trouvée pour ce cas que c'est une autre question comment modifier les itinéraires à la carte si la façon dont vous avez besoin (dans le cas où vous en avez vraiment besoin, ce que je ne crois pas que ce soit une bonne idée whatif certains :nom d'utilisateur est photos 😉 il y a un conflit dans les routes, etc...)
- Être Reposante n'a rien à voir avec l'URL réelle de segments. Il a à voir avec l'utilisation de la requête HTTP verbes (GET, POST, PUT, DELETE) pour déterminer l'action appropriée. Comme pour la vanité de l'Url (comme
/:username
), c'est vraiment commun. Alors qu'il a été débattu ad nauseam ici, c'est pas de la partie à l'origine des problèmes. Vous pouvez facilement vérifier si un nom d'utilisateur n'est pas dans une liste de noms réservés, et parce que mes voies soient en place correctement, il ne peut pas remplacer l'un de mes autres voies.
Vous devez vous connecter pour publier un commentaire.
Avez-vous envisagé d'utiliser un peu imbriquées route dans ce cas?
Peu Profondes Route De Nidification
Parfois, imbriqués les ressources peuvent produire des encombrants Url. Une solution à ce
est d'utiliser peu profondes route de nidification:
Cela permettra à la reconnaissance des routes suivantes:
La meilleure façon de le faire dépend de l'application, mais dans mon cas, c'est certainement l'Option B. l'Utilisation des espaces de routes, je suis capable d'utiliser un module de conserver les différentes préoccupations séparée en différents contrôleurs dans un très propre. Je suis également utiliser un espace de noms spécifique contrôleur ajoutez des fonctionnalités à tous les contrôleurs dans un espace de nom particulier (en ajoutant, par exemple, un before_filter pour vérifier l'authentification et l'autorisation pour toutes les ressources dans l'espace de noms).
J'ai fait quelque chose de semblable à cela dans une de mes applications. Vous êtes sur la bonne voie. Ce que j'ai fait a été de déclarer imbriquée des ressources, et de construire la requête à l'aide du flexible arel-en fonction de la syntaxe de l'Enregistrement Actif dans Rails 3. Dans votre cas, il pourrait ressembler à quelque chose comme ceci:
to_param
sur le modèle de l'Utilisateur. Si c'est aussi important pour l'itinéraire commence par le nom d'utilisateur (par opposition à/users/:username
), de la recherche autour, que cette question a déjà été posée plusieurs fois sur DONC. Personnellement, je ne pense pas que c'est une bonne approche, car il vous met en place pour le risque de conflits avec les futurs contrôleurs. Il est facile de faire quelque chose de différent dans la vue, vous pouvez écrire la logique conditionnelle dépend de la présence deparams[:user_id]
.to_param
semble comme il pourrait être un décent option pour faire de chemin aides de travail sans passer le nom d'utilisateur explicitement. Court de cela, cependant, je crois que j'aime la clarté que "Option 2" offre; les barrières sait déjà à charger les photos différemment, et la vue de droite est chargé à chaque fois. Concernant les conflits de noms sur l'url de vanité, je l'ai fait dans le passé sans problèmes. Aussi longtemps que vous le mettez dernière et contraindre les itinéraires des utilisateurs valides, il fonctionne bien. Dans ce cas, j'ai le "/photos/*" pour garder sauvages Url routé comme "/nom d'utilisateur/foobar", trop.Vous pouvez définir une autre voie pour obtenir les photos pour un utilisateur comme suit:
Mais je conseille juste à l'aide de la imbriquée des ressources que Jimmy posté ci-dessus étant donné que c'est la solution la plus souple.
Obtenu à l'exemple de:
http://jasoncodes.com/posts/rails-3-nested-resource-slugs
Juste appliqué que dans mon projet en cours.