Reputation: 33795
I have setup friendly_id perfectly, and whereas my old URLs used to look like:
/posts/1
....now they look like: /posts/article-title-here
.
I was able to get rid of the posts
in the URL altogether...so that it it just looks like: /article-title-here
, by doing this in my routes:
resources :posts, path: ''
get '/:friendly_id', to: 'posts#show'
But what I want to happen now is if someone goes to /posts/article-title-here
it automatically redirects them to /article-title-here
and doesn't throw an error like it does now.
How do I do that?
Update:
This is my 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
Update 2:
When I try the suggestion of @rich-peck of this:
get '/:friendly_id', to: 'posts#show'
get 'posts/:friendly_id', to: 'posts#show'
get '/posts/:id' => redirect("/%{id}")
This is the result:
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:
Upvotes: 1
Views: 78
Reputation: 76774
Just do this:
#config/routes.rb
resources :posts, path: "" #-> domain.com/:id
get "/posts/:id" => redirect("/%{id}")
You can read up more on redirection here
Updated by OP:
This is what my final routes looks like - that actually works:
#config/routes.rb
resources :posts, path: ''
get 'posts/:id' => redirect("/%{id}")
get '/:friendly_id', to: 'posts#show'
get 'posts/:friendly_id', to: 'posts#show'
It is important that the redirect happens before the friendly_id
routes, otherwise this won't work.
Upvotes: 2
Reputation: 5556
Set standard resources route:
resources :posts
get '/:friendly_id', to: 'posts#show'
And in controller:
def show
if request.path.start_with?('/posts')
redirect_to "/#{params[:id]}"
end
# load post
end
Upvotes: 0