Create a Photo Gallery with Rails and Cloudinary

Photo by Jon Tyson on Unsplash

Create a Photo Gallery with Rails and Cloudinary

ยท

2 min read

Here are some notes I've taken to my future self while implementing a gallery of photos in Rails and using Cloudinary. Note that I also prepare the same Cloudinary bucket to be used by both development and production, but in a way that we can stay in their free tier (a single bucket). Hope this is useful to others too.

Scaffolding

rails g scaffold property name description:text
rails db:migrate

Setup Cloudinary

bundle add cloudinary

config/initializers/cloudinary.rb ๐Ÿ”ป

Cloudinary.config do |config|
  config.cloud_name = Rails.application.credentials.dig(Rails.env.to_sym, :cloudinary, :cloud_name)
  config.api_key = Rails.application.credentials.dig(Rails.env.to_sym, :cloudinary, :api_key)
  config.api_secret = Rails.application.credentials.dig(Rails.env.to_sym, :cloudinary, :api_secret)
  config.secure = true
  config.cdn_subdomain = true
end
EDITOR=vim rails credentials:edit
development:
  cloudinary:
    cloud_name: dxe1hjkoi
    api_key: 361019726125669
    api_secret: Cn6tHfSf019278367sZoO083eOI
rails active_storage:install
rails db:migrate

config/storage.yml ๐Ÿ”ป

cloudinary:
  service: Cloudinary
  folder: <%= Rails.env %>

config/environments/development.rb ๐Ÿ”ป

config.active_storage.service = :cloudinary

Upload photos

app/models/property.rb ๐Ÿ”ป

class Property < ApplicationRecord
  has_many_attached :photos
end

app/views/properties/_form.html.erb ๐Ÿ”ป

= simple_form_for @property do |f|
  = f.input :photos, as: :file, input_html: { multiple: true }

app/controllers/properties_controller.rb ๐Ÿ”ป

def property_params
  params.require(:property).permit(:name, :description, photos: [])
end

Show photos

app/views/properties/show.html.erb ๐Ÿ”ป

- @property.photos.each do |photo|
  = cl_image_tag photo.key, height: 500, width: 1108, crop: :fill

Delete photos

config/routes.rb ๐Ÿ”ป

  resources :properties do
    resources :photos do
      match '/remove', to: 'properties#remove', via: 'delete'
    end
  end

app/controllers/properties_controller.rb ๐Ÿ”ป

  def remove
    # TODO: for security reasons delete in the scope of the account
    # For instance: current_account.properties.find(params[:property_id])
    # Disclaimer: currently I don't have an account so I can't do it now
    @property = Property.find(params[:property_id])
    @photo = @property.photos.find(params[:photo_id])
    @photo.purge
    redirect_to property_path(@property), notice: "Photo was successfully removed."
  end

app/views/properties/_form.html.slim ๐Ÿ”ป

.card-columns.mt-3
  - @property.photos.each do |photo|
    .card
      .card-body
        = cl_image_tag photo.key, height: 200, width: 400, crop: :fill, class: 'img-fluid'
      .card-footer
        = link_to "Remove", property_photo_remove_path(@property, photo), \
          method: :delete, data: { confirm: 'Are you sure you want to delete this photo?' }, \
          class: 'btn btn-light btn-block'

Did you find this article valuable?

Support Flavio Wuensche by becoming a sponsor. Any amount is appreciated!

ย