By now you should have a blog with users, administrators and even a tag system as of [part 3]({{< relref "/dev/rails-blog-part-3.md" >}}) in this series, so now we're onto something for greater aesthetics. In this case, custom URLs for posts and tags. We'll start by running: ```shell rails g migration add_url_to_tags_and_users ``` The above generates a migration that we can open up (usually in `db/migrate`) and add the following inside the `change` method: ```ruby add_column :tags, :url, :string add_column :posts, :url, :string ``` This will add columns for the url component to both the Tag and Post model and we can send these changes to the database with `rake db:migrate`. Next add the following to both app/models/post.rb and app/models/tag.rb before the `end` keyword: ```ruby validates :url, uniqueness: true def to_param url end def self.find_by_param(input) find_by_url(input) end ``` These tell Rails to use the `:url` parameter when making and using URLs such as localhost:3000/post/welcome instead of localhost:3000/post/1 and also makes sure that the URL parameter is unique in the table. Lastly it also creates a method usable by the Tag and Post classes that allows a user to find by the url parameter with `find_by_param` which will be used later.. Next edit the `create` and `update` methods in app/controllers/posts_controller.rb and put the following near the top, directly above `@post.tags = ready_tags`: ```ruby @post.url = post_params[:title].squish.downcase.tr(" ","_").gsub(/[^0-9A-Za-z_]/, '') ``` Now we need to find every instance of `.find(params[:id])` and change it to `.find_by_param(params[:id])` allowing us to use the new `:id` parameter (which will be the `:url` variable) as the identifier. Do that in both app/controllers/posts_controller.rb and app/controllers/tags_controller.rb. Next we'll want to modify the `ready_tags` private function to look like this: ```ruby def ready_tags tags = tag_params[:tag_ids].split(/,\s*/) tags_ready = [] tags.each do |tag| temp = Tag.find_by_url(tag.squish.downcase.tr(" ","_").gsub(/[^0-9A-Za-z_]/, '')) if temp == nil temp = Tag.create(name: tag, url: tag.squish.downcase.tr(" ","_").gsub(/[^0-9A-Za-z_]/, '')) end tags_ready.push(temp) end tags_ready end ``` This makes sure it's searching for tags by unique URL and also creates the tag with a unique URL as well. You will also need to modify your app/controllers/posts_controller.rb `create` method, wrapping everything in the method in the following block: ```ruby if post_params[:title].squish.downcase.tr(" ","_").gsub(/[^0-9A-Za-z_]/, '') == 'new' redirect_to posts_path, notice: 'Post cannot be titled "new".' else [EXISTING CODE] end ``` Now do similar with the `update` method, wrapping it all in the following: ```ruby if post_params[:title].squish.downcase.tr(" ","_").gsub(/[^0-9A-Za-z_]/, '') == 'new' render :edit else [EXISTING CODE] end ``` This prevents someone creating a post that would have the URL 'new', which would break the resourceful routing rails uses. You'll also need to modify config/routes.rb, removing the line `resources :tags` and replacing it with: ```ruby get '/tags', to: 'tags#index', as 'tags' get '/tags/:id', to: 'tags#show' delete '/tags/:id', to: 'tags#destroy' ``` This non-resourcefully defines the routes used for tags (`index`, `show`, `destroy`) and also allows us to create a tag labelled "new" without breaking anything. You should now have a working, aesthetically pleasing URL system for your blog. This will likely be the last of the tutorials in this series on building a blog in Rails, the implementation you've created up till now should have a number of standard and useful features for blogs and you should have enough expertise to start developing your own features and branching out further.