Home Ruby Tutorial Ruby Tutorial: Making Your Own Blog With Ruby on Rails

Ruby Tutorial: Making Your Own Blog With Ruby on Rails

128
0
SHARE
Ruby Tutorial
Ruby Tutorial

# Introduction

Ruby on Rails is an awesome framework for easily and quickly building up a web application. By using Rails framework, you can build many different web apps, including a blog platform. In this tutorial we will give you a basic guide to build a blog platform on your own, using Ruby on Rails framework. After reading and doing the step we provide you in this tutorial, hopefully you can run a basic blog platform, with function such as posting, index page, and so on. What you need to follow this tutorial is a computer with Ruby on Rails installed. An internet connection to install Ruby gems is also needed to install the required gems if you don’t have it yet in your computer.

 

# The Basic: Start Your New Project

Using your terminal (command prompt/powershell/GIT bash powered with Rails framework in Windows, linux terminal, or else depends or what your operating systems is), navigate to your Rails working directory and generate new Rails application.

 

rails new myblog -T

 

That code will generate a new Rails application called ‘myblog’ and install a couple of gems for our new application. The -T flag tells Rails to generate our new apps without a test suite. By default some gems are installed when we create new application. Gems are like plugins or libraries with some functionality installed to satisfy some specific needs.

 

# Generating our post model

After you’ve created your new apps, let’s create our post model. Let’s understand how our post model will work first. For every post we want to be able to add a title and body of text. This should be saved to a database whenever the submit button is clicked. Therefore we need a posts table with title and body columns. So let’s do the work. Go to your terminal and let’s generate our model. Type in:

 

rails g model Post title:string body:text

 

That command will create some files in our apps. One of the files created is a migration file in the directory db/migrate. After this we need to migrate our database. Open your terminal, and type this.

 

rake db:migrate

 

And that should do it.

 

# Installing Simple Form and Bootstrap-Sass

Let’s install simple_form and bootstrap-sass to beautify our work. Go your terminal and navigate to your ruby working directory to run gem command. Type like this.

 

gem ‘simple_form’, ‘~> 3.2’

gem ‘bootstrap-sass’, ‘~> 3.3’

 

After that run this code:

 

bundle install

 

# Setting up bootstrap-sass

 

Open your terminal, go to your Ruby working directory and navigate to app/assets/javascript/application.js. In this file, add a new line before the line that requires jquery:

 

//= require bootstrap-sprockets

 

After that, rename aplication.css in (ruby working directory/app/assets/stylesheets/) to application.scss. Open this file with a text editor, add this new line and then save it.

 

@import “bootstrap-sprockets”;

@import “bootstrap”;

 

After that, let’s generate simple_form by running this command through our terminal:

 

rails generate simple_form:install –bootstrap

 

Some files and directories will be created for us to ensure our simple_form can work.

 

# Setting up the Posts Controller and Views

To make us can control our post, we need to create a post controller. Let’s create a PostsController before moving on to our model. Type this command in your terminal.

 

rails g controller Posts

 

Let’s set it up. Type this the code below (the line with a hashtag in the beginning means it is only a comment, so you can leave it if you wanted to) into app/controllers/posts_controller.rb:

 

class PostsController < ApplicationController

before_action :find_post, only: [:edit, :update, :show, :delete]

 

# Index action to render all posts

def index

@posts = Post.all

end

 

# New action for creating post

def new

@post = Post.new

end

 

# This block of code will create action to saves the post into database

def create

@post = Post.new

if @post.save(post_params)

flash[:notice] = “Successfully created post!”

redirect_to post_path(@post)

else

flash[:alert] = “Error creating new post!”

render :new

end

end

 

# Defining an edit function

def edit

end

 

# Defining an update action of our posts

def update

if @post.update_attributes(post_params)

flash[:notice] = “Successfully updated post!”

redirect_to post_path(@posts)

else

flash[:alert] = “Error updating post!”

render :edit

end

end

 

# The show action renders the individual post after retrieving the id

def show

end

 

# The destroy action removes the post permanently from the database

def destroy

if @post.destroy

flash[:notice] = “Successfully deleted post!”

redirect_to posts_path

else

flash[:alert] = “Error updating post!”

end

end

 

private

 

def post_params

params.require(:post).permit(:title, :body)

end

 

def find_post

@post = Post.find(params[:id])

end

end

 

After doing this, we will have a list of actions to create a new post. But we still have to handle our views. Let’s take care of that next.

 

# Creating our Views

Go ahead and create the following files in app/views/posts directory:

 

index.html.erb

edit.html.erb

new.html.erb

show.html.erb

_form.html.erb

 

We need a ‘magical’ form that will be rendered whenever a post is to be created. We will make a partial. By making a partial we can share the form across the new and edit pages. It allows us to reuse our layouts across multiple pages. A partial starts with the underscore _ symbol. And here’s the code.

 

#app/views/posts/_form.html.erb

 

<%= simple_form_for @post do |f| %>

<% if @post.errors.any? %>

<div id=”error_explanation”>

<h2>

<%= “#{pluralize(@post.errors.count, “error”)} prohibited this post from being saved:” %>

</h2>

<ul>

<% @post.errors.full_messages.each do |msg| %>

<li>

<%= msg %>

</li>

<% end %>

</ul>

</div>

<% end %>

 

<div class=”form-group”>

<%= f.input :title, class: “form-control” %>

</div>

 

<div class=”form-group”>

<%= f.input :body, :as => :ckeditor, input_html: {:ckeditor => {:toolbar => ‘FULL’}}, class: “form-control” %>

</div>

 

<div class=”form-group”>

<%= f.button :submit %>

</div>

<% end %>

 

With that done we can just render the form in our new and edit pages. Let’s do another work to make sure we can render our form in new.html.erb and edit.html.erb

 

# Code for viewing our new post

 

<h2>Create New Post</h2>

 

<%= render “posts/form” %>

View for Editing a Post

 

# Code for view when we are editing a post

 

#app/views/posts/edit.html.erb

<h2>Edit Post</h2>

 

<%= render “posts/form” %>

 

# View for our Index

 

Having a blog without an index page is not really catchy isn’t it? That’s why we need an index page. Let’s build up our index page. With your terminal go and edit app/views/posts/index.html.erb, type the following code:

 

<div class=”container”>

<div class=”col-sm-10 col-sm-offset-1 col-xs-12 blog-content”>

<% @posts.each do |post| %>

<div class=”col-xs-12″>

<div class=”text-center”>

<h2><%= post.title %></h2>

<h6><%= post.created_at.strftime(‘%b %d, %Y’) %></h6>

</div>

 

<div>

<%= raw(post.body).truncate(358) %>

</div>

 

<div class=”text-center”>

<%= link_to “READ MORE”, post_path(post) %>

</div>

<br>

</div>

<% end %>

</div>

</div>

 

# View for Displaying Posts

After you finished creating a page view for our index, let’s make another view controller to display our post. Navigate and edit app/views/posts/show.html.erb. Type the following code:

 

<div class=”col-sm-11 col-xs-12 blog-content”>

<h2 class=”text-center”><%= @post.title %></h2>

<h5 class=”text-center”><%= @post.created_at.strftime(‘%b %d, %Y’) %></h5>

<div><%= raw @post.body %></div>

</div>

 

For now we have successfully created the necessary view files for creating, editing and viewing a posts. But we have more to do. From your terminal or editor, navigate to config/routes.rb. Edit it by type in the following codes:

 

Rails.application.routes.draw do

root to: “posts#index”

 

resources :posts

end

 

By doing this, we set the root of our application as posts/index. It means each time a visitor points her/his browser to the root of our application, they will be presented with the index page of our post.

 

The resources line provides us with all of the actions available, and the include: new, index, create, show, edit, update and destroy.

 

# Installing CKeditor

To make, update, edit, and delete a blog post we need an editor. We will use Ckeditor as our editor for this tutorial. This is where your internet comes to act. Lets install the ckeditor gem. Open up your Gemfile and paste in the line below and save.

 

gem ‘ckeditor’, ‘~> 4.1’,

 

After that go to your terminal to install it with the code like what we’ve typed when we install simple_form and bootstrap-sass. Let’s go ahead and generate the necessary files for ckeditor to work with. Run the command below from your terminal:

 

rails generate ckeditor:install –orm=active_record –backend=carrierwave

 

And just like before, migrate your database after this installation.

 

# Load the Ckeditor

 

After we have installed ckeditor, we need to make sure it is loaded every time we run our blog. Go to app/assets/javascripts/application.js. Edit this file by adding this code below just above the tree line.

 

//= require ckeditor/init

 

Next, we have to make a directory called ckeditor in app/assets/javascripts, then create a new file called config.js in the directory you just created to personalize CKeditor. Paste in the code below (you can change it if you wanted to set up differently):

 

CKEDITOR.editorConfig = function(config) {

config.language = ‘en’;

config.width = ‘700’;

config.filebrowserBrowseUrl = “/ckeditor/attachment_files”;

config.filebrowserImageBrowseLinkUrl = “/ckeditor/pictures”;

config.filebrowserImageBrowseUrl = “/ckeditor/pictures”;

config.filebrowserImageUploadUrl = “/ckeditor/pictures”;

config.filebrowserUploadUrl = “/ckeditor/attachment_files”;

 

config.toolbar_Pure = [

‘/’, {

name: ‘basicstyles’,

items: [‘Bold’, ‘Italic’, ‘Underline’, ‘Strike’, ‘Subscript’, ‘Superscript’, ‘-‘, ‘RemoveFormat’]

}, {

name: ‘paragraph’,

items: [‘NumberedList’, ‘BulletedList’, ‘-‘, ‘Outdent’, ‘Indent’, ‘-‘, ‘Blockquote’, ‘-‘, ‘JustifyLeft’, ‘JustifyCenter’, ‘JustifyRight’, ‘JustifyBlock’, ‘-‘, ‘BidiLtr’, ‘BidiRtl’]

}, {

name: ‘links’,

items: [‘Link’, ‘Unlink’]

}, ‘/’, {

name: ‘styles’,

items: [‘Styles’, ‘Format’, ‘Font’, ‘FontSize’]

}, {

name: ‘colors’,

items: [‘TextColor’, ‘BGColor’]

}, {

name: ‘insert’,

items: [‘Image’, ‘Table’, ‘HorizontalRule’, ‘PageBreak’]

}

];

config.toolbar = ‘Pure’;

return true;

};

 

And here we are. For now, try to start your rails server, and then open your browser and navigate to http://localhost:3000/posts/new to see your new blog.

 

# Enabling image uploading

A blog post without an image feature is not really cool, isn’t it? That’s why we have to add image uploading function to power up our blog post. To do this we will a gem called carrierwave. Open your Gemfile and add it in.

gem ‘carrierwave’

gem ‘mini_magick’

Carrierwave helps you enable seamless upload of images in your Rails application. Mini_Magick helps in the processing of your images. Don’t forget to run ‘bundle install’ to install your new gem file. After you’ve installed it, we need run the generator command to generate some important files to ensure CarrierWave works with CKEditor. Type in this code in your terminal:

 

rails generate ckeditor:install –orm=active_record –backend=carrierwave

 

This command will tell Rails to generate some outputs for us. After this migrate your database by running the command: rake db:migrate. Run rails server to start up your server. Point your browser to http://localhost:3000/posts/new. And voila! You should see an icon representing an image that you can use to upload your image and sent it to your post.

 

# Enabling authentication

 

This is our blog. So only us that is supposedly can create and delete or doing others as we please to our post. To do that, we have to make an authentication mechanism to make sure not everybody can modify our blog post. To do this, we will use a gem called devise. Devise is is a flexible authentication solution for Rails.

 

Firstly, add devise gem to your Gemfile,

 

gem ‘devise’

 

Install it using ‘bundle install’ command and after that run this code to generate necessary files for devise.

 

rails g devise:install

 

After that there will be two new files in your application. They are config/initializers/devise.rb and config/locales/devise.en.yml. The first is an initializer that is required for Devise to work in your application. When we look at the output displayed by our terminal, we have to perform some task. Navigate to config/environments/development.rb and paste in the line below just above the end line:

 

config.action_mailer.default_url_options = { host: ‘localhost’, port: 3000 }

end

 

This will help us to handle our mailer in the development environment. The next task to do is to add a block of code in our application layout for flash messages. Go ahead and open app/views/layouts/application.html.erb Paste the line below above the yield block:

 

<p class=”notice”><%= notice %></p>

<p class=”alert”><%= alert %></p>

 

Now let’s generate our Admin model by running the command below:

 

rails generate devise Admin

 

And that should do it! When that is done, migrate the database again.

 

You will want to generate Devise views. To do this run the command below:

 

rails g devise:views admin

 

For the purpose of this tutorial, we have to edit a few pages Devise generated for us (even it does creates a lot of files for us) to make it more user-friendly. Paste the code below into their respective files: This is the file that will handle the editing of our Admin profile.

 

# Edit in file views/admins/registrations/edit.html.erb

 

<div class=”col-sm-offset-4 col-sm-4 col-xs-12″>

<h2 class=”text-center”>Edit <%= resource_name.to_s.humanize %></h2>

 

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, class: “form” }) do |f| %>

<%= devise_error_messages! %>

 

<div class=”form-group”>

<%= f.label :email %><br />

<%= f.email_field :email, autofocus: true, class: “form-control” %>

</div>

 

<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>

<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>

<% end %>

 

<div class=”form-group”>

<%= f.label :password %> <i>(leave blank if you don’t want to change it)</i><br />

<%= f.password_field :password, autocomplete: “off”, class: “form-control” %>

</div>

 

<div class=”form-group”>

<%= f.label :password_confirmation %><br />

<%= f.password_field :password_confirmation, autocomplete: “off”, class: “form-control” %>

</div>

 

<div class=”form-group”>

<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />

<%= f.password_field :current_password, autocomplete: “off”, class: “form-control” %>

</div>

 

<%= f.submit “Update”, class: “btn btn-primary btn-lg” %>

<% end %>

 

<h3 class=”text-center”>Cancel my account</h3>

 

<p>Unhappy? <%= button_to “Cancel my account”, registration_path(resource_name), data: { confirm: “Are you sure?” }, method: :delete, class: “btn btn-danger btn-lg” %></p>

 

<%= link_to “Back”, :back, class: “btn btn-primary btn-lg” %>

 

</div>

 

Next we should work on the sign up page for our Admin. We will edit the default pages by adding some snippets of code from bootstrap. Copy and paste the code below into views/admins/registrations/new.html.erb.

 

<div class=”col-sm-offset-4 col-sm-4 col-xs-12″>

<h2 class=”text-center”>Sign up</h2>

 

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: {class: “form”}) do |f| %>

<%= devise_error_messages! %>

 

<div class=”form-group”>

<%= f.label :email %><br />

<%= f.email_field :email, autofocus: true, class: “form-control” %>

</div>

 

<div class=”form-group”>

<%= f.label :password %>

<% if @minimum_password_length %>

<em>(<%= @minimum_password_length %> characters minimum)</em>

<% end %><br />

<%= f.password_field :password, autocomplete: “off”, class: “form-control” %>

</div>

 

<div class=”form-group”>

<%= f.label :password_confirmation %><br />

<%= f.password_field :password_confirmation, autocomplete: “off”, class: “form-control” %>

</div>

 

<%= f.submit “Sign up”, class: “btn btn-primary btn-lg” %>

<% end %>

 

</div>

<%= render “admins/shared/links” %>

 

So we’ve finished our business with the registrations of our Admin. You should have noticed that Devise groups all of these pages into separate folders. This happens because there are different controllers handling each of this pages. We have another homework to do. We need to edit the sign in page of our admin. Paste the following code into views/admins/sessions/new.html.erb

 

<div class=”col-sm-offset-4 col-sm-4 col-xs-12″>

<h2 class=”text-center”>Log in</h2>

 

<%= form_for(resource, as: resource_name, url: session_path(resource_name), html: {class: “form”}) do |f| %>

<div class=”form-group”>

<%= f.label :email %><br />

<%= f.email_field :email, autofocus: true, class: “form-control” %>

</div>

 

<div class=”form-group”>

<%= f.label :password %><br />

<%= f.password_field :password, autocomplete: “off”, class: “form-control” %>

</div>

 

<% if devise_mapping.rememberable? %>

<div class=”form-group”>

<%= f.check_box :remember_me %>

<%= f.label :remember_me %>

</div>

<% end %>

 

<%= f.submit “Log in”, class: “btn btn-primary btn-lg” %>

<% end %>

 

</div>

 

<%= render “admins/shared/links” %>

 

Devise has a partial that it uses to render common links across all the pages we have seen above. This partial is in a different folder called shared. Let us edit that as well. Paste the code below in views/admins/shared/_links.html.erb

 

<div class=”col-sm-offset-4 col-sm-4 col-xs-12″>

<% if controller_name != ‘sessions’ %>

<%= link_to “Log in”, new_session_path(resource_name) %><br />

<% end %>

 

<% if devise_mapping.registerable? && controller_name != ‘registrations’ %>

<%= link_to “Sign up”, new_registration_path(resource_name) %><br />

<% end %>

 

<% if devise_mapping.recoverable? && controller_name != ‘passwords’ && controller_name != ‘registrations’ %>

<%= link_to “Forgot your password?”, new_password_path(resource_name) %><br />

<% end %>

 

<% if devise_mapping.confirmable? && controller_name != ‘confirmations’ %>

<%= link_to “Didn’t receive confirmation instructions?”, new_confirmation_path(resource_name) %><br />

<% end %>

 

<% if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != ‘unlocks’ %>

<%= link_to “Didn’t receive unlock instructions?”, new_unlock_path(resource_name) %><br />

<% end %>

 

<% if devise_mapping.omniauthable? %>

<% resource_class.omniauth_providers.each do |provider| %>

<%= link_to “Sign in with #{OmniAuth::Utils.camelize(provider)}”, omniauth_authorize_path(resource_name, provider) %><br />

<% end %>

<% end %>

</div>

 

All of the edits above will provide a great experience for our admins. To make our changes work, we have to edit a line in Devise initializer. Go to line 223, of your Devise initializer; config/initializers/devise.rb, uncomment the line and change false to true, so it looks like this:

 

config.scoped_views = true

 

Now type in your browser address and press enter to go to http://localhost:3000/admins/sign_in and see the new format of your sign in page.

 

# Navigation bar

 

To bring greater experience for our readers, we have to add a navigation bar so that users can easy move from one page to another. Let’s do it by creating a navigation partial, by creating _navigation.html.erb inside app/views/layouts/.

 

Paste the following code into the file you just created.

 

<nav class=”navbar navbar-default”>

<div class=”container-fluid”>

<!– Brand and toggle get grouped for better mobile display –>

<div class=”navbar-header”>

<button type=”button” class=”navbar-toggle collapsed” data-toggle=”collapse” data-target=”#navbar-collapse” aria-expanded=”false”>

<span class=”sr-only”>Toggle navigation</span>

<span class=”icon-bar”></span>

<span class=”icon-bar”></span>

<span class=”icon-bar”></span>

</button>

<a class=”navbar-brand” href=”#”>Scotch Blog</a>

</div>

<div class=”collapse navbar-collapse” id=”navbar-collapse”>

<ul class=”nav navbar-nav navbar-right”>

<li><%= link_to ‘Home’, root_path %></li>

<% if admin_signed_in? %>

<!–This block is only visible to signed in admins –>

<li><%= link_to ‘New Post’, new_post_path %></li>

<li><%= link_to ‘My Account’, edit_admin_registration_path %></li>

<li><%= link_to ‘Logout’, destroy_admin_session_path, :method => :delete %></li>

<!– The block ends here –>

<% else %>

<li><%= link_to ‘Login’, new_admin_session_path %></li>

<% end %>

</ul>

</div>

</div>

</nav>

 

Before the navigation bar can be visible on your website you need to render it. In this case, the rendering will be done from the application layout. Goes app/views/layouts/application.html.erb. It should be like this.

 

<!DOCTYPE html>

<html>

<head>

<title>ScotchBlog</title>

<%= stylesheet_link_tag ‘application’, media: ‘all’, ‘data-turbolinks-track’ => true %>

<%= javascript_include_tag ‘application’, ‘data-turbolinks-track’ => true %>

<%= csrf_meta_tags %>

</head>

<body>

<!– Render navigation bar –>

<%= render “layouts/navigation” %>

<p class=”notice”><%= notice %></p>

<p class=”alert”><%= alert %></p>

<div class=”container-fluid”>

<%= yield %>

</div>

 

</body>

</html>

 

If you reload your browser, you will see that a navigation bar is there to help you out.

 

# Authenticate Action

 

We have our admin set up. Now we have to set up the authentication ; we need just one line to do so. Navigate to app/controllers/posts_controller.rb and add this line of code.

 

#This authenticates admin whenever a post is to be created, updated or destroyed.

before_action :authenticate_admin!, except: [:index, :show]

 

We are using the before_action callback provide by Rails to make sure that whenever ANY action EXCEPT index and show is called, authentication will be requested.

 

# Validation

 

One more thing, we need to validate the presence of title and body each time a new post is going to be created. Of course we do not want our admins to create posts that have no title or body. Validation is always done in the Model. Navigate to your Post model (app/models/post.rb) and make it look like this:

 

class Post < ActiveRecord::Base

#This validates presence of title, and makes sure that the length is not more than 140 words

validates :title, presence: true, length: {maximum: 140}

#This validates presence of body

validates :body, presence: true

end

 

# Admin Actions on Index Page

 

To make work easy for the admin, and for the sake of user experience, it is wise that we include links for easy navigation in the index. But we have to make sure that this link only visible to admins. Go to app/views/posts/index.html.erb and add the code below:

 

<div class=”container”>

<div class=”col-sm-10 col-sm-offset-1 col-xs-12″>

<% @posts.each do |post| %>

<div class=”col-xs-12 text-center”>

<div class=”text-center”>

<h2><%= post.title %></h2>

<h6><%= post.created_at.strftime(‘%b %d, %Y’) %></h6>

</div>

<div>

<%= raw(post.body).truncate(358) %>

</div>

<div class=”text-center”>

<%= link_to “READ MORE”, post_path(post) %>

</div>

<% if admin_signed_in? %>

<%= link_to “Show”, post_path(post), class: “btn btn-primary” %>

<%= link_to “Edit”, edit_post_path(post), class: “btn btn-default” %>

<%= link_to “Delete”, post_path(post), class: “btn btn-danger”, data: {:confirm => “Are you sure?”}, method: :delete %>

<% end %>

<hr />

</div>

<% end %>

</div>

</div>

 

Let’s try to logout if you are logged in. We should not be able to create a new post when you point your browser to http://localhost:3000/posts/new. Now only admins can manage your blog.

 

# Conclusion

 

We have successfully created a new blog platform, which has the basic blog functionality using Ruby on Rails. You can modify and extend your blog to satisfy your own need, as many as you wanted it to be. Thank you for following this tutorial, have a nice coding day!

 

The articles sources for this tutorials are from scotch.io, “Building Blog with Ruby”, by kinsomicotre. The link is:

  • https://scotch.io/tutorials/build-a-blog-with-ruby-on-rails-part-1
  • https://scotch.io/tutorials/build-a-blog-with-ruby-on-rails-part-2

LEAVE A REPLY

Please enter your comment!
Please enter your name here