Skip to content
Menu
Railshero
  • Blog
  • About Me
  • Contact Me
  • Privacy Policy
Railshero
Creating A Photo Album App With Rails

Creating A Photo Album App With Rails

Posted on July 18, 2021July 19, 2021 by Rails Hero

Creating a bare bone photo album app

Today, i’ll show you how to create a basic photo album app with rails6, i’ll be using active_storage to manage uploads/attachments of our photo album. This app will be a very basic photo gallery/ablum app with just the bare bones, so no special styles, no file validations, authentication, and also no direct uploads or uploads to S3 or anything of that sort. In my future blog posts i’ll post an update on how to implement those features, but for now lets stick just with the bare bones.

Getting Started

To get started lets create a new rails app, lets call it ‘photoalbum’.

rails new photoalbum

After that, we’ll add image processing gem to our gemfile, and run bundler. This gem helps in resizing, cropping and processing of images.

#File: Gemfile
gem 'image_processing', '~> 1.2'
bundle install

Then we’ll install active storage for image attachment uploads.

rails active_storage:install

Now, lets create a new scaffold, our model name will be album and will contain a title and a description for the album.

rails g scaffold album title:string description:text

Now run the migrations

rails db:migrate

Adding Attachments

Now, lets start creating the actual part of our application that is to manage the uploads/attachments and display the uploaded photos.

The Model

In our album model we’ll add a has_many_attached type of attachment so that an album can contain multiple photos, we’ll call our attachment ‘album_photos’.

#File: app/models/album.rb
class Album < ApplicationRecord
has_many_attached :album_photos
end

The Controller

In our albums controller, we’ll permit the ‘album_photos’ parameter, album_photos will be sent as an array, since we want multiple uploads, so keep that in mind. We’ll also have to add a new method to delete the photo attachment, later if we want to remove the photos individually, instead of deleting the whole album.

#File: app/controllers/albums_controller.rb
class AlbumsController < ApplicationController
#....other methods.....
   def delete_album_photos
      attachment = ActiveStorage::Attachment.find(params[:id])
      attachment.purge
      redirect_back(fallback_location: albums_path)
   end
#....other methods.....
 
private
   def set_album
      @album = Album.find(params[:id])
   end
   def album_params
      params.require(:album).permit(:title, :description, album_photos: [])
   end
end

Routes

For the delete attachment method, we’ll also have to add a new route, and also i added a root route for our app, this will redirect to albums#index page.

#File: config/routes.rb
Rails.application.routes.draw do
   root to: 'albums#index'
   resources :albums do
      member do
         delete :delete_album_photos
      end
   end
end

The Views

In our albums’ form partial, i added a new file field to upload our photo/image files, i added ‘multiple: true’ to enable multiple uploads.

#File: app/views/albums/_form.html.erb
<div class="field">
<%= form.label :title %>
<%= form.text_field :title %>
</div>

<div class="field">
<%= form.label :description %>
<%= form.text_area :description %>
</div>

<div class="field">
<%= form.label :album_photos %>
<%= form.file_field :album_photos, multiple: true %>
</div>

In our Albums’ show page, i added a image tag with a image variant, of size 150×150. This will show our uploaded photos as thumbnails, and also i added a link_to to the original file of the photos, it will open the photo in a new tab and show us the full size photo. I also added a download link and file size info for the image files.

#File: app/views/albums/show.html.erb
<p><strong>Title:</strong><%= @album.title %></p>
<p><strong>Description:</strong><%= @album.description %></p>
<%= link_to 'Edit', edit_album_path(@album) %> |
<%= link_to 'Back', albums_path %>

<hr>

<% @album.album_photos.order("created_at DESC").each do |album_photos| %>
<div style="margin: 5px;border: 1px solid #ccc;float: left;width: 150px;">
<%= link_to image_tag(album_photos.variant(resize_to_fill: [150, 150]), style: "width: 100%;height: auto;", alt: album_photos.filename.to_s), album_photos, target: "_blank"%>

<div style="padding: 8px;text-align: center;font-size: 0.7em">
<%= number_to_human_size(album_photos.byte_size.to_i) %>
<%= link_to "Download", album_photos, target: "_blank" %>
<%= link_to 'Delete', delete_album_photos_album_url(album_photos), method: :delete, data: { confirm: 'Are you sure?' } %>
</div>
</div>
<% end %>

Active Storage Initializer

I also added a new initializer for active storage, in app/initializers/ and named it ‘active_storage.rb’, i had to do this to disable a feature called ‘replace_on_assign_to_many’, that is enabled by default. If this is enabled, every time i edit/update an album with a new set of photos, it will delete the previously uploaded attachments and replace it with new ones, by default. After disabling this feature, please don’t forget to restart your rails server.

here’s my blog post about this feature: active_storage.replace_on_assign_to_many

#File: config/initializers/active_storage.rb
Rails.application.config.active_storage.replace_on_assign_to_many = false

 

The End Result

So this is how the end result looks like, you can check out the complete source code of this app on my github page: https://github.com/railshero/simple_photo_album

I can now create a new album, edit/delete previously created albums, add new photos to new/existing albums or even remove them individually.

album photos show page
album photos show page

The source of the royalty free images used above is from pexels.com

new album page
new album page
edit album page
edit album page

Final Thoughts

So, as i said earlier, this app is just a bare bone app. I created the entire app in just about 10 minutes, so there are no special features like file validations, authentication, etc, there’s not even a pagination feature. In my future blog post, i’ll post and update on this app. But you can implement those features yourself, if you wish to do so.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Tags

active record active storage assets assign to many associations attachment attachments authentication authorization avatar bootstrap cdn config database deploy deployments devise DRY environment variables file uploads Gemfile gems has_many helpers heroku index indexing initializer javascript pagination parameters postgres production public routes.rb ruby gem ruby gems search sendgrid server smtp stylesheets variants views voting

Recent Posts

  • Understanding the DRY Principle in Rails
  • Building Multi-tenant Applications with Rails
  • Rails Basics: Templating Engines
  • Deploying With Capistrano
  • Automated Testing in Rails

Archives

  • July 2023
  • June 2023
  • October 2021
  • September 2021
  • August 2021
  • July 2021

Categories

  • Active Record
  • Activity Logging
  • Apps
  • Assets
  • Attachments
  • Audio
  • Authentication
  • Authorization
  • Deployments
  • Error Pages
  • File Uploads
  • General
  • Heroku
  • Heroku
  • Pagination
  • Rails Basics
  • RubyGems
  • Search Engine Optimization
  • Search/Indexing
  • Testing
  • User Interface
  • Video
  • Views & Templating
  • Voting
  • Web Security
©2025 Railshero | Theme: Wordly by SuperbThemes
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept All”, you consent to the use of ALL the cookies. However, you may visit "Cookie Settings" to provide a controlled consent.
Cookie SettingsAccept All
Manage consent

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary
Always Enabled
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Non-necessary
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.
SAVE & ACCEPT