【问题标题】:Rails 4 Blog /:year/:month/:title with clean routingRails 4 博客 /:year/:month/:title 与干净的路由
【发布时间】:2014-08-20 08:08:11
【问题描述】:

在 Rails 4 中还有另一种更简洁的方式来实现路由,例如:

/blog/2014/8/blog-post-title
/blog/2014/8
/blog/2014
/blog/2014/8/tags/tag-1,tag-2/page/4
/blog/new OR /blog_posts/new

我使用FriendlyId(以及acts-as-taggable 标记参数和kaminari 页面参数)尝试了以下操作:

blog_post.rb

 extend FriendlyId
 friendly_id :slug_candidates, use: [:slugged, :finders]

 def to_param
   "#{year}/#{month}/#{title.parameterize}"
 end

 def slug_candidates
 [
    :title,
    [:title, :month, :year]
 ]
 end

 def year
   created_at.localtime.year
 end

 def month
   created_at.localtime.month
 end

routes.rb

  match '/blog_posts/new', to: 'blog_posts#new', via: 'get'
  match '/blog_posts/:id/edit', to: 'blog_posts#edit', via: 'get'
  match '/blog_posts/:id/edit', to: 'blog_posts#update', via: 'post'
  match '/blog_posts/:id/delete', to: 'blog_posts#destroy', via: 'destroy'
  match '/blog(/page/:page)(/tags/:tags)(/:year)(/:month)', to: 'blog_posts#index', via: 'get'
  match '/blog/:year/:month/:title', to: 'blog_posts#show', via: 'get'
  resources 'blog', controller: :blog_posts, as: :blog_posts

已使用资源,因此可以正常使用路径和 url 助手。

这可行(减去更新),但感觉非常难看。有没有更好的办法?

【问题讨论】:

  • 你不需要资源中包含的新建、编辑、更新、销毁路由...
  • 我需要这些,所以它是 /blog_posts/action 而不是 /blog/action,否则它会将操作解释为年份参数,例如year="new"。也许对于这些路由定义还有另一种方法?

标签: ruby-on-rails routing friendly-id


【解决方案1】:

Friendly_ID

我认为您的主要问题是您试图将 /:year/:month/:tags 保留在一组参数中 - 您更适合单独发送它们,并根据需要构建资源:

#config/routes.rb
scope "/blog" do
   resources :year, controller :blog_posts, only: :show, path: "" do
      resources :month, controller : blog_posts, only: :show, path: "" do
         resources :title, controller: blog_posts, only: :show, path: ""
      end
   end
end
resources :blog_posts, path: :blog -> domain.com/blog/new

这看起来不守规矩,但有望提供一种路由结构,让您能够将特定请求发送到您的 Rails 应用程序 (domain.com/blog/...),并由 blog_posts#show 操作处理它们

以下是我的处理方式:

#app/controllers/blog_posts_controller.rb
Class BlogPostsController < ApplicationController

   def show
      case true
         when params[:year].present?
           @posts = Post.where "created_at >= ? and created_at < ?", params[:year]
         when params[:month].present?
           @posts = Post.where "created_at >= ? and created_at < ?", params[:month]
         when params[:id].present?
           @posts = Post.find params[:id]
      end
   end

end

#app/views/blog_posts/show.html.erb
<% if @posts %>
  <% @posts.each do |post| %>
    <%= link_to post.title, blog_post_path(post) %>
  <% end %>
<% end %>

<% if @post %>
   <%= link_to post.title, blog_post_path(post) %>
<% end %>

--

蛞蝓

要创建 slug,您只需将标题用于 friendly_id:

#app/models/blog_post.rb
Class BlogPost < ActiveRecord::Base
   extend FriendlyId
   friendly_id :title, use: [:slugged, :finders]
end

这可能无法开箱即用(事实上,它可能不会),但我想证明的是,我认为你最好分开处理参数/year/ month / title 进入你的控制器

【讨论】:

  • 您好,感谢您的回答。我已经使用它进行了一些调整(问题已更新)。 /blog/new 有效,/blog/1/edit。但是最后一个参数总是作为 id 给出,例如/blog/2014 导致id: 2014 和/blog/2014/5/blah-blah 导致year_id:2014, month_id:6, id: blah-blah。此外,将补丁更新到完整的/blog/2014/8/blah,这是没有路径的。我可以手动使用 post in form 吗?
  • 啊,我认为如果您将resources :blog ref 放在其他人的下方,这可以解决 - 让我为您更新!
  • 嗯,我刚试过这个,但仍然是同样的问题,/blog/new 和编辑操作现在不起作用。
  • 哈哈好吧。你能在你的问题中分享你的rake routes吗?
  • 是的,完全令人震惊……让一切都清晰可见。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-24
  • 2015-08-15
  • 1970-01-01
相关资源
最近更新 更多