Building a Blog with PDF Uploader in Rails 5

Goal

Build a blogging feature for use on a nonprofit corporation website. Implement create, read, update, and delete actions for the blog, which will be used to make public announcements with PDFs attached.

edit_upload_blog

Plan

Within an existing Rails 5 app, use the Trix gem and the Paperclip gem along with basic Rails features to build CRUD actions for a blog post.

Instructions

Add gems to the gemfile and run bundle

  1. gem "paperclip","~> 5.0.0"
  2. gem 'trix'

Follow Paperclip install instructions

For Mac OS X, I did:

  1. Install an image processor: brew install imagemagick.
  2. Because I want PDF uploads, I also needed Ghostscript:
    brew install gs

Follow Trix install instructions

  1. In the application stylesheet (a css or scss file in the assets directory), paste
    *= require trix
  2. In the application.js file (also in the assets directory), paste //= require trix

Create relationships and validations in models

I created validations for a post to have a title and content. Paperclip also has a validation for an document’s content type, as well as a required has_attached_file method, where specifications can be added such as the file’s width and height (more likely used for an image than a PDF).
class Post < ApplicationRecord

belongs_to :user
validates :title, presence: true
validates :content, presence: true
has_attached_file :document
validates_attachment_content_type :document, :content_type => ['application/pdf']

end

class User < ApplicationRecord

has_many :posts

end

Migrations

I generated a migration for posts and later ran a Paperclip migration. The Paperclip migration gives a datatype of attachment, which is reflected in the schema after the migration has been run with four new columns: the attachment name, content type, file size, and time of update. (This can also be run as one migration. Check out the Paperclip documentation.)

  1. rails generate migration CreatePosts title:string user_id:integer content:text
  2. rails generate paperclip post document

Routes

I want full CRUD actions for my users and posts, so I used Rails resources.

resources :users
resources :posts

Controller

I haven’t included my entire posts controller, but as an example, here’s the create controller action with strong params. Check out my github repository to see all of my controller actions.

class PostsController < ApplicationController

def create
@post = Post.new(post_params)
@post.user = current_user
# current_user is a method defined in the Application Controller
if @post.save
flash[:notice] = "Post published!"
redirect_to :users
else
flash[:notice] = "posts must have a title and content"
render 'new'
end
end

private

def post_params
params.require(:post).permit(:title, :content, :document)
end

end

Views

To add a Trix text editor in my post new and post edit view, I simply used Trix’s built-in method, which can be used with Rails form_for.

The Paperclip attachment is equally easy to implement with form_for using the file_field method.

New Post Form

<%= form_for @post do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>

<%= f.label :content %>
<%= f.trix_editor :content %>

<%= f.label :document %>
<%= f.file_field :document %>

<%= f.submit 'submit', :class => "waves-effect waves-light amber lighten-1 white-text btn" %>
<% end %>

Post Show Page

When rendering the post content, I used the Rails sanitize method in order to safely render user input. Sanitize removes any non-whitelisted content from the html.

<%= @post.title %>
<%= link_to @post.upload_attachment_file_name, @post.upload_attachment.url %>
<%= sanitize @post.content %>

Conclusion

While I’ve removed some unnecessary code for simplicity and readability, these steps include everything needed to create a functioning blog feature. Check out my github repository to see the full project.

Resources

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s