Лучший способ сделать "/ blogs /: year /: month /: day /: permalink" маршруты в Rails? - PullRequest
6 голосов
/ 08 января 2010

У меня есть blog_controller с ресурсом Blog, поэтому у меня есть ваши типичные маршруты прямо сейчас:

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

Но вот что я хочу:

/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?

Я знаю, что могу сделать это с помощью комбинации map.resources и map.connect, но у меня есть много просмотров, которые ссылаются на другие страницы через "new_blog_path" и т. Д., И я не хочу, чтобы иди и отредактируй их. Это возможно только с map.resources? Это может быть нелегко, но я не против того, чтобы быть умным. Я думал о чем-то вроде:

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

Но я не уверен, как это работает с такими действиями, как 'new' или 'create', а также дает мне маршрут типа /2010/01/08/blogs/1-to_param-etc с блогами в середине URL.

Итак, есть ли какое-нибудь умное решение, которое я упускаю, или мне нужно идти по маршруту map.connect?

Ответы [ 2 ]

13 голосов
/ 10 января 2010

Я недавно столкнулся с той же проблемой, и, хотя это может быть не то, что вы ищете, это то, что я сделал, чтобы позаботиться об этом:

конфиг / 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>

и ради полноты:

blog_entry.rb:

before_save :create_permalink

#...

private

def create_permalink
  self.permalink = title.to_url
end

Метод #to_url происходит от rsl's Stringex .

Я все еще новичок в Rails (и программировании), но это, наверное, самый простой способ сделать это. Это не RESTful способ решения проблем, поэтому, к сожалению, вы не получите преимущества map.resources.

Я не уверен (потому что я не пробовал), но вы можете создать соответствующих помощников в application_helper.rb, чтобы переопределить помощников маршрута по умолчанию для blog_path и др. Если это сработает, вам не придется менять код вашего представления.

Если вы любите приключения, вы можете проверить Routing Filter . Я решил использовать его, но это похоже на излишество для этой задачи.

Также, если вы не знаете, две вещи, которые вы можете сделать, чтобы проверить ваши маршруты / пути из скрипта / консоли:

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

и

app.blog_entry_path(@entry)

Удачи!

2 голосов
/ 08 января 2010

Из API Документов :

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

Используя вышеприведенный маршрут, URL "localhost: 3000 / article / 2005/11/06" отображается на

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

Похоже, вы хотите сделать то же самое, но суффикс пост-слаг. Ваши новые и редактируемые ссылки все равно будут ссылками "старой школы", такими как "localhost: 3000 / article / 1 / edit" и "localhost: 3000 / article / new" Просто ссылка "показать" должна быть обновлена ​​с этим.

...