2010-01-08 3 views
6

Ich habe eine blogs_controller mit einem Blog-Ressource bekam, also habe ich jetzt Ihre typische Routen bekam wie folgt:Der beste Weg, um "/ Blogs /: Jahr /: Monat /: Tag /: Permalink" Routen in Rails zu tun?

/blogs/new 
/blogs/1 
/blogs/1/edit #etc 

Aber hier ist, was ich will:

/blogs/new 
/blogs/2010/01/08/1-to_param-or-something 
/blogs/2010/01/08/1-to_param-or-something/edit #etc 
... 
/blogs/2010/01 # all posts for January 2010, but how to specify custom action? 

Ich weiß, dass ich kann dies mit einer Kombination aus map.resources und map.connect tun, aber ich habe viele Ansichten, die über "new_blog_path" usw. zu anderen Seiten verlinken, und ich möchte diese nicht bearbeiten müssen. Ist das mit map.resources alleine möglich? Es mag nicht einfach sein, aber ich bin nicht dagegen, clever zu sein. Ich dachte an so etwas wie:

map.resources :blogs, :path_prefix => ':year/:month/:day', :requirements => {:year => /\d{4}/, :month => /\d{1,2}/, :day => /\d{1,2}/} 

Aber ich bin mir nicht sicher, wie das funktioniert mit Aktionen wie ‚neu‘ oder ‚schaffen‘, und es gibt mir auch eine Route wie /2010/01/08/blogs/1-to_param-etc mit Blogs in der Mitte des URL

Also, gibt es eine clevere Lösung, die ich vermisse, oder muss ich die map.connect Route gehen?

Antwort

13

ich in das gleiche Problem vor kurzem lief, und, wenn dies nicht sein kann, was Sie suchen, das ist, was ich davon nehmen getan Pflege:

config/routes.rb :

map.entry_permalink 'blog/:year/:month/:day/:slug', 
        :controller => 'blog_entries', 
        :action  => 'show', 
        :year  => /(19|20)\d{2}/, 
        :month  => /[01]?\d/, 
        :day  => /[0-3]?\d/ 

blog_entries_controller.rb:

def show 
    @blog_entry = BlogEntry.find_by_permalink(params[:slug]) 
end 

blog_entries_helper.rb:

def entry_permalink(e) 
    d = e.created_at 
    entry_permalink_path :year => d.year, :month => d.month, :day => d.day, :slug => e.permalink 
end 

_entry.html.erb:

<h2><%= link_to(entry.title, entry_permalink(entry)) %></h2> 

und der Vollständigkeit halber:

blog_entry.rb:

before_save :create_permalink 

#... 

private 

def create_permalink 
    self.permalink = title.to_url 
end 

Die Methode #to_url stammt von rsls Stringex.

Ich bin noch neu in Rails (und Programmierung) selbst, aber das ist wahrscheinlich der einfachste Weg, um darüber zu gehen. Dies ist keine REST-konforme Vorgehensweise, so dass Sie leider nicht von map.resources profitieren.

Ich bin mir nicht sicher (weil ich es nicht versucht habe), aber Sie könnten in der Lage sein, die entsprechenden Helfer in application_helper.rb zu erstellen, um die Standard-Route-Helfer für blog_path, et al. Wenn das funktioniert, müssen Sie Ihren Ansichtscode nicht ändern.

Wenn Sie sich abenteuerlustig fühlen, können Sie sich unter Routing Filter umsehen. Ich dachte darüber nach, es zu benutzen, aber es scheint für diese Aufgabe übertrieben zu sein. Auch

, wenn Sie nicht wissen, zwei Dinge, die Sie tun, um Ihre Routen/Wege aus Skript/Konsole zu testen:

rs = ActionController::Routing::Routes 
rs.recognize_path '/blog/2010/1/10/entry-title' 

und

app.blog_entry_path(@entry) 

Viel Glück!

+0

Danke Jay, das ist eine _sehr_ nette Beschreibung, die mir heute viel Zeit gespart hat! –

+0

Tolle Erklärung! –

+0

Was wäre die Schiene 3 Version der Route? – sguha

2

Vom API Docs:

map.connect 'articles/:year/:month/:day', 
      :controller => 'articles', 
      :action  => 'find_by_date', 
      :year  => /\d{4}/, 
      :month  => /\d{1,2}/, 
      :day  => /\d{1,2}/ 

die Route über Verwendung der URL "localhost: 3000/articles/2005/11/06" Karten

params = { :year => '2005', :month => '11', :day => '06' } 

Sieht aus wie Sie wollen, das gleiche, aber Suffix eine Post-Slug. Ihre neuen und bearbeiteten Links wären immer noch die "Old School" -Links, wie "localhost: 3000/articles/1/edit" und "localhost: 3000/articles/new". Nur der Link "show" sollte damit aktualisiert werden.

+0

hey jarrett, danke für die post. Die Schnecke ist kein Problem, to_param kann dafür sorgen. Was ich wirklich tun möchte, ist "map.connect" loszuwerden und dies in einem Aufruf von "map.resources" zu behandeln, so dass ich nicht alle meine bestehenden Aufrufe von blog_path (@blog) usw. modifizieren muss. Idealerweise Ich möchte url_for (@blog) aufrufen und etwas wie "/ blogs/2010/01/08/1-to_param-or-something" zurückbekommen, was meiner Meinung nach mit map.connect nicht möglich ist. Ich vermute, was ich will, ist nicht möglich (ist dieses URL-Format RESTful überhaupt?), Ich versuche nur zu sehen, ob jemand kreative Lösungen hatte. – carpeliam

Verwandte Themen