How to Setup Image URLs on Your Rails API in 10 Easy Steps: A Step-by-Step Guide

Koray Ozkal
4 min readNov 12, 2020

Would you like to add images to your web app? Confused by all the information you came across in Stack Overflow and got lost in gem hunting? This article is for you!

First of all, there are many different ways to accomplish setting up, storing, rendering, and uploading an image in your app. There are so many fancy gems that could help you. However, if you are racing against time to deliver a project, sometimes it really helps to keep it simple and go back to basics. For this article, I decided to follow a very simple method: adding an image URL represented as a string and transmitting it by using JSON. I will use Rails as an API for creating my back-end and JavaScript for my front-end. (If you are interested in a step-by-step guide to building a rails API, please also check my Startup Magazine article, Beginner’s Guide to Building a Rails API)

STEP 1 — Add the IMAGE URL as a STRING when generating models

rails g model Comicbook title image_url publisher_id:integer number:integer artist writer --no-testframework

Quick note rails will default to a string if we don’t specify a type for our attributes. Also, don’t forget to run rails db:create && rails db:migrate to complete creating your database and migration.

STEP 2 — Add the IMAGE URL to your SEED data

Now let’s go to our seeds file db/seeds.rb and make sure we have the image_url included while creating a new comicbook in our seed data.

Comicbook.create(title: “Flash Rebirth”, image_url: “https://images-na.ssl-images-amazon.com/images/S/cmx-images-prod/Item/48457/DIG010147_1._SX360_QL80_TTD_.jpg", artist: “Ethan Van Sciver”, writer: “Geoff Johns” , publisher_id: dc.id)

STEP 3— Render JSON from a Rails controller

A JSON string contains either an array of values or an object (an associative array of name/value pairs). By using render json: in our Rails controller, we take the entire Comicbook model, have Rails convert them to a JSON string( JavaScript Object Notation), and send them out on request. This is useful for AJAX calls in JavaScript where you want to return JavaScript objects. I am copying index controller action as an example.

class ComicbooksController < ApplicationControllerdef indexcomicbooks= Comicbook.all
render json: comicbooks
#if you are using a serializer
#render json: ComicbookSerializer.new(comicbooks)
end

*Don’t forget to also add a create action if you are letting your end-user to submit a form. Make sure image_url is listed in your STRONG PARAMS, in your controller if you are letting end-user submit information and create a new instance of comicbook with a mass assignment of params.

class ComicbooksController < ApplicationController#YOUR ACTIONS HERE FIRSTprivatedef comicbook_params
params.require(:comicbook).permit(:title, :writer, :artist,
:image_url, :publisher_id,)
end

STEP 4 — *Only if you are using Serializers — Don’t forget to add image_url as an attribute in your Serializer Class.

class ComicbookSerializer  include FastJsonapi::ObjectSerializer
attributes :title, :writer, :artist, :image_url, :publisher_id,
:publisher
end

STEP 5 — Test your data.

Now, if we set everything else right with our application, visiting or fetching http://localhost:3000/comicbooks will now produce our array of comicbook objects and each object will have an image_url!!!

{
"id": "2",
"type": "comicbook",
"attributes": {
"title": "Flash Reborn",
"writer": "Geoff Johns",
"artist": "Ethan Van Sciver",
"image_url": "https://images-na.ssl-images-amazon.com/images/S/cmx-images-prod/Item/48457/DIG010147_1._SX360_QL80_TTD_.jpg",
"publisher_id": 2,
"publisher": {
"id": 2,
"name": "DC Comics",
"created_at": "2020-10-25T07:05:29.840Z",
"updated_at": "2020-10-25T07:05:29.840Z"
}
}
}

NOW everything is set on our back-end app and we can fetch the image URLs on our Javascript front-end! We will create the folders and files below:

1- comicbook_frontend/index.hmtl 
2- comicbook_frontend/src/index.js
3- comicbook_frontend/src/comicbook.js

STEP 6 — Set up your index.html and connect with your JS files

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Comicbook Geek App</title><!-- JS Connection Tags --><script src="src/index.js" charset="utf-8"></script><script type="text/javascript" src="src/comicbook.js"></script><script type="text/javascript" src="src/index.js"></script></head><body><h1>COMICBOOK APP</h1><br><br><h2>MY COMICBOOKS</h2><div id="comicbooks-container"></div></body></html>

STEP 7 — Setup your endpoint in your index.js

const endPoint = "http://localhost:3000/comicbooks"

Make sure it is in your global scope!

STEP 7— Create your Comicbook class and constructor and add your image_url attribute

class Comicbook {constructor(comicbook, comicbookAttributes) {this.id = comicbook.id;//IMPORTANT:Don't forget to list all the other attributes here!!!this.image_url = comicbookAttributes.image_url;Comicbook.all.push(this); 
// pushing each new instance of Comicbook object to an array
}

STEP 8 — Now we are creating a renderComicbook() function

renderComicbook() {  return `  <div data-id=${this.id}>  <img src=${this.image_url} height=”300" width=”200">  <p>${this.title}</p>  //IMPORTANT!: Don't forget to list all the other attributes!!! </div><br><br>`;  }}Comicbook.all = []; //where we are pushing each new instance

STEP 9— Create a function for fetching comicbooks for index action, iterate a new comicbook instance with forEach, and render .

function getComics() {  fetch(endPoint)     .then(response => response.json())     .then(comics => {       comics.data.forEach(comicbook => {     let newComicbook = newComicbook(comicbook,comicbook.attributes)     document.querySelector(‘#comicbooks-container’).innerHTML +=           newComicbook.renderComicbook()     })    })}

STEP 10— Open your index.hmtl and test!

Yes!!! We did it!!

Happy coding and please let me know if you have any comments or suggestions!

Resources:

https://medium.com/swlh/beginners-guide-to-building-a-rails-api-7b22aa7ec2fb)

--

--

Koray Ozkal

Marketing Strategist @Intel, Tech Blogger, Rock Guitarist, Hockey & Basketball fan.