如何为friendly_id生成的URL捕获两条路由?

时间:2014-08-30 20:43:19

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

我已经完美地设置了friendly_id,而我以前的旧网址看起来像是:

/posts/1 ....现在看起来像是:/posts/article-title-here

我能够完全删除网址中的posts ...所以它只是看起来像/article-title-here,在我的路线中执行此操作:

  resources :posts, path: ''
  get '/:friendly_id', to: 'posts#show'

但我现在想要发生的事情是,如果有人转到/posts/article-title-here,它会自动将它们重定向到/article-title-here并且不会像现在这样抛出错误。

我该怎么做?

更新

这是我的PostsController

class PostsController < ApplicationController
  before_action :set_post, only: [:show, :edit, :update, :destroy]
  load_and_authorize_resource

  def index
    @posts = Post.all.order("created_at desc")
  end

  def show
  end

  def new
    @post = Post.new(parent_id: params[:parent_id])
  end

  def edit
  end

  def create
    @post = current_user.posts.new(post_params)

    respond_to do |format|
      if @post.save
        format.html { redirect_to @post, notice: 'Post was successfully created.' }
        format.json { render :show, status: :created, location: @post }
      else
        format.html { render :new }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @post.update(post_params)
        format.html { redirect_to @post, notice: 'Post was successfully updated.' }
        format.json { render :show, status: :ok, location: @post }
      else
        format.html { render :edit }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @post.destroy
    respond_to do |format|
      format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_post
      @post = Post.friendly.find(params[:id])          
    end

    def post_params
      params.require(:post).permit(:status, :title, :photo, :file, :body, :parent_id)
    end
end

更新2:

当我尝试@ rich-peck的建议:

  get '/:friendly_id', to: 'posts#show'
  get 'posts/:friendly_id', to: 'posts#show' 
  get '/posts/:id' => redirect("/%{id}")

结果如下:

Started GET "/posts/pnpyo-saddened-at-passing-of-roger-clarke" for 127.0.0.1 at 2014-09-02 02:29:14 -0500
  ActiveRecord::SchemaMigration Load (1.0ms)  SELECT "schema_migrations".* FROM "schema_migrations"
Processing by PostsController#show as HTML
  Parameters: {"friendly_id"=>"pnpyo-saddened-at-passing-of-roger-clarke"}
Completed 404 Not Found in 93ms

ActiveRecord::RecordNotFound - Couldn't find Post without an ID:

2 个答案:

答案 0 :(得分:2)

这样做:

#config/routes.rb
resources :posts, path: "" #-> domain.com/:id
get "/posts/:id" => redirect("/%{id}")

你可以read up more on redirection here

由OP更新:

这就是我的最终路线 - 实际上是有效的:

  #config/routes.rb
  resources :posts, path: ''
  get 'posts/:id' => redirect("/%{id}")
  get '/:friendly_id', to: 'posts#show'
  get 'posts/:friendly_id', to: 'posts#show' 

重定向发生在friendly_id路线之前非常重要,否则无法正常工作。

答案 1 :(得分:0)

设置标准资源路线:

resources :posts
get '/:friendly_id', to: 'posts#show'

在控制器中:

def show
  if request.path.start_with?('/posts')
    redirect_to "/#{params[:id]}"
  end

  # load post
end