- set up paperclip and all external dependencies on your machine
- set up an account on AWS to store our uploaded images inside AWS S3
- set up a rails project with paperclip
- understand the how and why, of a rails model with an image attribute
From the paperclip docs
Paperclip is intended as an easy file attachment library for ActiveRecord. The intent behind it was to keep setup as easy as possible and to treat files as much like other attributes as possible. This means they aren't saved to their final locations on disk, nor are they deleted if set to nil, until ActiveRecord::Base#save is called. It manages validations based on size and presence, if required. It can transform its assigned image into thumbnails if needed, and the prerequisites are as simple as installing ImageMagick (which, for most modern Unix-based systems, is as easy as installing the right packages). Attached files are saved to the filesystem and referenced in the browser by an easily understandable specification, which has sensible and useful defaults.
- to get Paperclip working on our Machines, we need to install a dependency that paperclip will be looking for, which is an external library called
ImageMagik
brew install imagemagick
- I apologize, but I have never installed it on windows nor do I have access to a windows machine to test on. After scouring the web, here are some resources that look good
- http://stackoverflow.com/questions/3036847/how-to-install-imagemagick-on-windows-7
- http://stackoverflow.com/questions/16655831/install-imagemagick-for-paperclip-gem-in-windows
- http://andystu.github.io/blog/2015/06/03/how-to-install-paperclip-for-rails-app-on-windows/
- here is a link to the ImageMagik binaries you will need: http://www.imagemagick.org/script/binary-releases.php#windows
- after we have set up our dependencies, we will need to set up our accounts on AWS. Let's do that!
- unfortunately, Amazon has changed their AWS sign up process from when I set up my original account, and we now have some additional hoops to jump through.
- first, navigate to this page: https://portal.aws.amazon.com/gp/aws/developer/registration/index.html?nc2=h_ct
- once there, it will ask you to enter your existing amazon information or to make a new account to use AWS
- from there, go through the sign up process. You will need to input your info, a credit card, and a phone number to verify. With the credit card option, select the
basicplan and you will not be charged
- with our AWS account set up, let's continue with our code.
- for this example, we are going to make a new rails app inside your favorite workspace and name it what you would like
- for the purpose of this example, I am going to call mine,
paperclip_test - let's setup our app! run
rails new paperclip_test -T --database=postgresqlinside your workspace where you want your repo - once we have set up our app, let's
cdinto it, and open withsubl .
- once inside our project folder, let's navigate to our
Gemfile - to use paperclip with AWS, we will need to use 3 different ruby gems, which we can do by adding the following to our
Gemfilegem "aws-sdk", "~> 2"gem "paperclip", "~> 5.0.0"gem "figaro"
- let's add all 3 of these to our gemfile and run
bundle install - after all our gems successfully install, we need to add an initializer for our
figarogem. we can do so by running this inside our project repobundle exec figaro install
- that was a lot of set up! now let's write some code
- our next step is to tell our rails app we will be using paperclip with S3, and to do so, we will have to modify our
development.rbfile - here is the config code to add to our
development.rbfile
config.paperclip_defaults = {
storage: :s3,
s3_protocol: 'http',
s3_credentials: {
bucket: ENV["AWS_S3_BUCKET"],
access_key_id: ENV["AWS_ACCESS_KEY_ID"],
secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"]
}
}- what the above code is saying to our app, is when our application is in development mode (
http://localhost:3000) we want to use AWS S3, which we have access to from ourawsgem - if you notice the
ENVabove, that is where figaro comes into play!
- to satisfy the code we wrote for our
development.rbfile, we need to get that info from AWS to put inside ourapplication.ymlfile. Let's do that! - navigate back to your AWS account and sign into the AWS Console (https://console.aws.amazon.com) if you don't already have it opened
- once signed in, find the
Storageoption, and in that list, look fors3. once you find it, click on it. - once inside our
S3section, let's create our first bucket. Find the bluecreate bucketbutton and click on it - when you click on it, it will pop up a modal with some info for your to fill out
- the name for our bucket must be unique, as it is shared across ALL OF AMAZON! try to find a unique name that you will remember
- for the region, select
US Standard
- once sucessfully created, you will be brought to a page that will show you some info about your bucket. Next, lets grab our keys.
- hit this link https://console.aws.amazon.com/iam/home?nc2=h_m_sc#security_credential which will take you to the page for our credentials
- once on that page, scroll down to the middle and click on
Access Keys (Access Key ID and Secret Access Key)and clickcreate new access key- once that button is clicked, it will generate a file with your info and it will download it. Open it up. this will give you your access key, and your secret key
- once we have these 2, let's open up our
application.ymlfile - add
AWS_ACCESS_KEY_ID:with your key, andAWS_SECRET_ACCESS_KEY:with your secret and save the file
- once on that page, scroll down to the middle and click on
- right now we have 2 of our 3 keys, let's get the remaining one.
- for our s3 bucket, add
AWS_S3_BUCKET:and then paste the name of your bucket
- for our s3 bucket, add
-
with all of our set up out of the way, we need to now set up our application. We are going to make a single table,
user, that will have the following attributes- name: string
- description: string
- image: attachment
-
to do this, we need to generate a blank migration file and model file, we can accomplish this with
rails g model User
-
now we have a blank migration file, so let's add some code to edit it to set up our database properly.
-
Inside of our migration let's add the following code
def change
create_table :users do |t|
t.string :name
t.string :description
t.attachment :image
t.timestamps null: false
end
end- we recognize the code for our string attributes, but we see a new attribute on our table called
attachment. This is from paperclip, and this is what we need to process our images - from here lets set up our database with the following commands
rake db:createrake db:migrate
- with a model set up, lets now add some code to our controllers and our routes
- inside of our
routes.rbfile, let's delete all of the comments and just add the single lineresources :users - now for practice, let's manually create a
userscontroller - once we have our controller, let's just add an index method to our file like so
class UsersController < ApplicationController
def index
end
end- the final step is to now add our view!
- go inside of
app/viewsand make a new folder calledusers. Insideusers, create anindex.html.erbfile - with all of this, let's fire up our server with
rails sand navigate tohttp://localhost:3000/users
-
with our barebones app set up, let's spend a couple minutes with a partner and add all of our
CRUDactions in our users controller. for right now, just leave them blank and we will fill them in as we go -
once we have all of our controller actions, let's just add one more method to our controller to sanitize our params like so
private
def user_params
params.require(:user).permit(:name, :description, :image)
end- with our controller, views, and routes set up, lets circle back to our users model and add our paperclip code
- paperclip comes with a way to make sure we have images associated with our chosen resource. To add paperclip to our
user model, we need to add a couple lines of code in ouruser.rbfile
class User < ActiveRecord::Base
has_attached_file :image, styles: { medium: "500x500>", thumb: "250x250>" }, presence: true
validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/
end-
the
has_attached_fileandvalidates_attachment_content_typeboth come from paperclip, and allow us to- allow the user to have the option to upload an image with
has_attached_file :image - make sure a user has an image when creating with
presence: true - to validate the content type to make sure we only accept images and not other file types
- allow the user to have the option to upload an image with
-
with the following on our model, let's navigate back to our views, and add a way to create new users
-
let's make a file for new users at
app/views/users/new.html.erb -
inside that file, add the following code
<%= form_for @user, url: users_path, html: { multipart: true } do |form| %>
<%= form.label :name %>
<%= form.text_field :name %><br>
<%= form.label :description %>
<%= form.text_field :description %><br>
<%= form.file_field :image %><br><br>
<%= form.submit 'Create User!' %>
<% end %>-
inside this form, we see something new:
html: { multipart: true }. What this does, is tell rails that we will be adding a file to our form -
now we need to edit our controller to add to the new and create action like so
def new
@user = User.new
end
def create
@user = User.create(user_params)
if @user.save
redirect_to users_path
else
render :new
end
end- now, let's go back to our form and add a new user. If everything goes well, we should be redirected back to our Users index page
- so we set up our app, we have written code to create users, and now we need a way to view them!
- let's go back into our index action of our controller and make a users variable
def index
@users = User.all
end- with that variable set, lets head back to our
index.html.erbto view them - lets add this code
<h1>Users</h1>
<hr>
<ul>
<% @users.each do |user| %>
<li><p><%= user.name %></p></li>
<li><p><%= user.description %></p></li>
<%= image_tag user.image.url %>
<%= link_to 'View user', user_path(user) %>
<% end %>
</ul>
<%= link_to 'Create User', new_user_path %>- with all of the code we currently have, get with your partner and add the rest of the code necessary to CRUD our resource!
