/photoblog-with-refile-gem-multiple-file-upload

Just a simple Ruby on Rails photoblog with refile gem as a demo for multiple file uploads with refile gem

Primary LanguageRuby

Uploading multiple files in Ruby on Rails can be a daunting task, specially for the beginners. For single file uploads it’s easy. You just need to add a single column to your database table(model) . Then usually people use Carrierwave or Paperclip gems. But for multiple files we have to deal with it differently. We need to have another model for our file attachments. It’s exactly like having a Comment model for your Post. There will be one to many relationship. One post has many comments. In the same way one post will have many images.

We will be using the Refile gem version 0.5.5 for multiple uploads. It’s the new kid in the block but pretty awesome. It’s easy to use and simple. At the end well create a simple photoblog like the picture below. You can add bootstrap and play with it to make it look beautiful

PhotoBlog Creating a photoblog with rails 4 and refile gem For this tutorial I have used ruby 2.2.2 and rails 4.2.2 !

If you don’t have ImageMagick installed already then use the following command

brew install imagemagick # OS X sudo apt-get install imagemagick # Ubuntu Now create a new app

rails new photo_blog Open your Gemfile and add the following lines.

gem “refile”, require: ‘refile/rails’, git: “github.com/refile/refile.git” gem “refile-mini_magick”

Go to terminal and run

bundle install

Then go to your /photo_blog folder and generate a scaffold for the blog posts.

rails g scaffold Post title:string body:text Then run migration

rake db:migrate

Now generate a model “Image” to hand image uploads

rails g model Image file_id:string post:references

Run migration

rake db:migrate

While creating the image model we use post:refenerences to add a foreign key to the post model. If you open your /photo_blog/db/schema.rb you’ll find the t.integer “post_id” in the images table. Rails also adds an post_id index to the images table as a reference.

Now open /photo_blog/app/models/image.rb . Include attachment :file and it should like

class Image < ActiveRecord::Base

belongs_to :post
attachment :file

end

Now open /photo_blog/app/models/post.rb and edit it like

class Post < ActiveRecord::Base

has_many :images, dependent: :destroy
accepts_attachments_for :images, attachment: :file

end

But if you want to keep old images when you edit the post and add more images then add append: true above . So it should look like

class Post < ActiveRecord::Base

has_many :images, dependent: :destroy
accepts_attachments_for :images, attachment: :file, append: true

end

Now go to your /photo_blog/app/views/posts/_form.html.erb and add the following lines just above <div class=“action”> or somewhere else if you know what you’re doing.

<div class=“field”>

<%= f.label :images_files %><br>
<%= f.attachment_field :images_files, multiple: true, presigned: true, direct: true %>

</div>

But we have to allow those images posted through posts controller. So open /photo_blog/app/controllers/posts_controller.rb. Scroll to the end of the file. Find def post_params . We need to add images_files: [] parameter there. it should look like

private

# Use callbacks to share common setup or constraints between   actions.
def set_post
  @post = Post.find(params[:id])
end

# Never trust parameters from the scary internet, only allow the white list through.
def post_params
  params.require(:post).permit(:title, :body, images_files: [])
end

We have our file uploader ready. We have update to our show and index page. Go to /photo_blog/app/views/posts/show.html.erb and add the Images: section or replace everything with the code below.

<p id=“notice”><%= notice %></p>

<p>

<strong>Title:</strong>
<%= @post.title %>

</p>

<p>

<strong>Images:</strong>
<% @post.images.each do |i| %>
  <%= attachment_image_tag(i, :file, :fill, 350, 350, format: "jpg") %>
<% end %>

</p>

<p>

<strong>Body:</strong>
<%= @post.body %>

</p>

<%= link_to ‘Edit’, edit_post_path(@post) %> | <%= link_to ‘Back’, posts_path %>

You can simply use <%= attachment_image_tag(i, :file) %> if you want to use original file dimension and format.

Now open your /photo_blog/app/views/posts/index.html.erb .

If you want to show all the photos in the index file then you can follow the same method as show page. I will just show the first uploaded file. find the code <td><%= post.title %></td> . Under that line type the following line

<td><%= attachment_image_tag(post.images.first, :file, :fill, 450, 450) %></td> We are almost done. Just open your photo_blog/config/routes.rb and set the index page

root ‘posts#index’

Well! We have got a blog with multiple images per post and text and description. You can use these methods to upload multiple files in Rails. To play with the images you might wanna use CSS/Javascript. You can see my demo files in Github Photoblog with Refile gem.