2013-02-18 7 views
17

Ich habe folgende Modelle:Rails geschachtelte Ressourcen und Routing - wie Controller zu brechen?

  • Beitrag
  • Tag
  • TaggedPost (von der Post und Tag leiten ihre Verbände durch has_many: durch)

Und ich habe die folgende routes.rb Datei :

resources :tags 

resources :posts do 
    resources :tags 
end 

Also wenn ich n. Avigieren Sie, sagen wir, /posts/4/tags, die mich in die Index-Aktion für den Tag-Controller mit dem post_id Wert im Parameter-Array gesetzt schießen wird. Cool.

Meine Frage ist, jetzt, da ich auf die geschachtelte Tags-Ressource unter Beiträge zugreifen, sollte ich den Tags-Controller immer noch treffen? Oder sollte ich zu diesem Zeitpunkt einen anderen Controller einrichten, der die geschachtelte Art von Tags behandelt? Ansonsten muss ich zusätzliche Logik in den Tags-Controller einbauen. Dies ist natürlich möglich, aber ist dies der übliche Weg, verschachtelte Routen und Ressourcen zu bearbeiten? Der Code, den ich in der Index-Aktion für die Etiketten controller haben, ist wie folgt:

TagsController.rb

def index 
    if params[:post_id] && @post = Post.find_by_id(params[:post_id]) 
    @tags = Post.find_by_id(params[:post_id]).tags 
    else 
    @tags = Tag.order(:name) 
    end 
    respond_to do |format| 
    format.html 
    format.json {render json: @tags.tokens(params[:q]) } 
    end 
end 

ich den Code in diesem Controller sehen zunehmend groß, wie ich für viele weitere planen Ressourcen, die mit Tag-Ressourcen verknüpft werden sollen. Gedanken darüber, wie man das durchbricht?

Zusammenfassung der Fragen:

  1. Wenn eine Ressource verschachtelt ist, sollte die verschachtelte Ressource durch einen anderen Controller, die die verschachtelte Natur der Ressource sein? Dies steht im Gegensatz dazu, den normalen Controller zu durchlaufen, wie ich in dem Codebeispiel, das ich bereitgestellt habe, bin.
  2. Wenn ja, wie sollten diese Controller benannt und eingerichtet werden?

Lassen Sie mich wissen, wenn Sie weitere Informationen benötigen.

Antwort

4

Alles, was Sie mit verschachtelten Ressourcen tun, ist das Ändern der Routing-URL. Sie müssen nur sicherstellen, dass Sie die richtige ID (in Ihrem Fall Post) an den Tag-Controller übergeben. Der häufigste Fehler ist die ID "Kann nicht gefunden ***".

, wenn Sie ein Profil Route in einem Benutzer Route nicht Nest tun würde es so aussehen

domain.com/user/1

domain.com/profile/2

, wenn Sie Nest die Routen wäre es

sein

domain.com/user/1/profile/2

, das alles ist, was es tut. nichts anderes. Sie benötigen keine zusätzlichen Controller. Getting Routing ist nur für Looks. Erlauben Sie Ihrem Benutzer, der Verbindung zu folgen. Das Wichtigste beim Verschachteln von Routen ist, dass Sie sicherstellen, dass Sie link_to auf den richtigen Pfad setzen.

wenn nicht verschachtelt: wäre es user_path und profile_path

sein, wenn es verschachtelt Sie user_profile_path verwenden müssten.

Rake Route ist Ihr Freund, um herauszufinden, wie sich die Routen geändert haben.

hoffe es hilft.

+0

Dies beantwortet tatsächlich den Kern meiner Frage ... Ich denke, die Logistik anders als das hängt wirklich auf meine Zwangsstörungen zu organisieren. –

+0

Bitte, um Ihrer zukünftigen Kollegen willen (und Sie selbst!), Lesen Sie auch @lazel Antwort! – gfd

+0

Ich werde einige hart verdiente Punkte ausgeben, um das zu senken. Bitte, fügen Sie bitte den verschachtelten Controller hinzu. – Drenmi

29

Ich denke, die beste Lösung Controller aufgeteilt ist:

resources :tags 

    resources :posts do 
     resources :tags, controller: 'PostTagsController' 
    end 

Und dann haben Sie 3-Controller. Optional können Sie PostTagsController von TagsController erben zu tun, so etwas wie:

class PostTagsController < TagsController 
     def index 
      @tags = Post.find(params[:post_id]).tags 
      super 
     end 
    end 

Wenn die Differenz nur der Abruf von Tags ist, können Sie:

class TagsController < ApplicationController 
     def tags 
      Tag.all 
     end 

     def tag 
      tags.find params[:id] 
     end 

     def index 
      @tags = tags 
      # ... 
     end 
     # ... 
    end 

    class PostTagsController < TagsController 
     def tags 
      Product.find(params[:product_id]).tags 
     end 
    end 

verwenden, die Methoden und einfach Tags in der außer Kraft setzen Erben Controller;)

+1

Diese Antwort ist viel sauberer und einfacher zu jedem kommenden Mitarbeiter IMHO zu verstehen. Ich weiß, Rails dreht sich alles um DRY, aber in diesem Fall sagt OP, 'Ich plane für viele zusätzliche Ressourcen mit Tag-Ressourcen zugeordnet werden, so dass die Unterscheidung jeder Zuordnung wird wahrscheinlich eine große Hilfe sein ... – gfd

+1

in der Controller-Option jetzt wir sollten stattdessen 'post_tags' haben. http://guides.rubyonrails.org/routing.html#specifying-a-controller-to-use –