The making of an Art Auction House

It’s almost officially been a week since our team in Le Wagon initiated our final commits to Github, tuned up the presentation and shipped our app to the world. In what amounted to a frantic two weeks, we hacked together a working Auction House that would make our 1st Grade teachers beam with pride. Baby, we made it!

So how did we do it?

Figuring out the user journey

The first step before any code was shipped involved figuring out what our users needed. Art has long been a platform for the wealthy to invest their wealth (and well, get richer) which has gated off purchasing art, specifically in auctions, for the rest of us.

That’s where we fits in: democratizing access to art auctions while providing artists quicker access to liquidity (without losing 15–25% at sale). For art enthusiasts, access to art and being able to purchase art seamlessly (without needing millions in the bank).

At it’s core there are two user journeys:

Artist; enabling them to create a profile, add/list artwork and setup an auction to sell off artwork.

User; enabling them to create a profile, and find auctions plus bid on items.

Developing the Database schema

What’s a nerd post without some DB schemas? The standard Database (tech stack for project listed end of page) for Rails is Postgres which is open source DB suitable for our production environment (untested at scale but good for theMVP).

We opted for 4 tables (listed below) with the primary being the User table and 3 others (Bids, Artworks and Auctions) having it’s Foreign key within them. Users are able to create Artworks & Auctions and a separate JOIN table is created called Auction Items which has a one-to-one relationship with Artworks and is assigned to one Auction.

DB schema for Art Auction

After an Auction Item is created a Bid will be created which will be assigned to one user (our auction style will be a blind auction where the bidder can only bid once).

User profile

Rails follows a MVC convention where Models represent the row in the DB (and an object within Ruby), the View is what the user sees, and Controller is where the logic is held.

In terms of workflow, Rails follows the convention of HTTP verb->Controller->View. Simply put, the request comes in — it gets assigned to a particular action within the Controller — the view is shown to the user which includes any data from the database or computation that is executed within the Controller.

The initial user journey started with a beautiful homepage (designed & executed by Josh Merrill), a truncated version can be seen top of the page. From there the user could enter a page to view all Auctions before being taken to their profile page (screenshot below).

Users were able to upload an image directly through the platform which on the backend uploaded the image to Cloudinary, created a representation in the DB via ActiveStorage and changed the users profile picture from the default grey box shown in the image. Snazzy.

The same approach was applied to Artworks which then showed up as an Artwork within the users profile.

Beyond the scope of the MVP, but it would be interesting to be necessary to be able verify the identity of the Artist and authenticity of the Artwork. This may be easier with Digital Assets such as NFT’s.

Auctions are the final step of the journey for the Artist (aside from bathing in tubs of cash Scrooge McDuck style). The Auction form asked for important details such as date/time when the Auction ends.

Auction page

The Auction page brings the Artist who created the Auction to the Auction page. Within here, upon request for the page it initiates an Action within the Auctions controller which assigns the Artworks that have been created to Auction Items. Once that one-to-one relationship has been created the Auction Items are shown in View for the page.

Outside of the scope of the MVP, the Artist would be able to choose which Artworks would be assigned to each Auction. As it stands, all Artworks that havn’t been assigned will be at Auction creation. Not an ideal UX.

A timer is also rendered on the Auction page leveraging code from W3Schools ( Once the countdown hit zero, JS manipulates the DOM to show text telling the user the Auction is done.

Bidding functionality

Here is where it gets fun! Now inside of the Auction Item a user is able to bid on an Item. This is done via Web Sockets and StimulusJS.

The initial setup included creating a form within the Auction Items page which listened for a Bid (in place of where the green box), which was added to the Bids table as an entry.

This created the required functionality except the user would need to press refresh in order to show all the Bids. Enter Action Cable. Action Cable integrates Web Sockets into a Rails app (using Ruby code) to be able to have the server push data.

Action Cable works on a subscription format where a “channel” is created that “subscribers” (anyone who is on a particular page with that ID) will receive the data.

Now that the Bid has been saved and broadcasted, we need Stimulus to listen on behalf of the Auction Item page and broadcast to all Subscribers.

When the data is pushed, magic happens (Any sufficiently advanced technology is indistinguishable from magic). Stimulus listens to the data as a Subscriber and injects the data into HTML which is rendered in real-time for the user. Neat, right?

The last step occurs once the timer ends. A POST request is pushed from JS to Rails which initiates a ‘change in ownership’ for the highest bidder. Rails returns a JSON object with the winners information and JS inputs via the DOM the HTML for the ‘congratulations’ green box shown at the start of this section.

Once the timer hits zero, a POST request is sent to the Rails server
A ‘finish bid’ action/method is initiated which changes the artworks owner and sends back a JSON object to JS to inject into the HTML

And that’s it!


I personally learned a ton around creating an app (but have a lot more to learn). I’m looking forward to learning more around JavaScript and how to have the front-end interact with API’s (React, anyone?).

I also learned a lot about working in teams (GitHub takes the headache out of a lot of it, while adding some migraines in the process). I’d like to thank my team: Fred Clausen, Tempestt Woodard and Josh Merrill. It was enjoyable building with you all!




Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store