Adding a backend Event data model

Now that we have our basic components in place for displaying events, let's switch to using real events data from a database, instead of dummy JSON.

We need to build a backend model for storing Event data.

Let’s generate a Rails model called Event with three fields for title, start time and location.

Note that we are using a start time so that we can introduce an event end time later.

$ rails g model Event title:string start_datetime:datetime location:string
Running this will generate the following migration:

db/migrate/20191104114940_create_events.rb:
class CreateEvents < ActiveRecord::Migration[6.0]
  def change
    create_table :events do |t|
      t.string :title
      t.datetime :start_datetime
      t.string :location
      t.timestamps
    end
  end
end

Let’s run the migration:

$ rails db:migrate
Now let’s add some seed data in the database. We can simply use the same data we used earlier in the controller in db/seeds.rb.

db/seeds.rb:
events = Event.create([
  {
    title: "London Retail Expo",
    start_datetime: "Mon, 14 Oct 2019",
    location: "London Excel Centre"
  },
  {
    title: "Enterprise Sales Training Workshop",
    start_datetime: "Tue, 15 Oct 2019",
    location: "Expert Sales Company Headquarters"
  },
  {
    title: "Ruby Hack Night",
    start_datetime: "Fri, 18 Oct 2019",
    location: "Learnetto Headquarters"
  },
  {
    title: "Beginners Salsa dance meetup",
    start_datetime: "Sat, 14 Oct 2019",
    location: "Bar Salsa"
  }
])

Then run:

$ rails db:seed
Let’s change the code for the index action in EventsController to use our newly seeded data. We’ll list the events in chronological order.

app/controllers/events_controller.rb:
  def index
    @events = Event.order('start_datetime ASC')
  end

Finally, we need to change the code in the Event component to use the new start_datetime field. Now that we’re using database values of type datetime instead of a simple string, they’ll be displayed as a datetime stamp, for example, 2019-10-14T00:00:00.000Z.

So, we need to format the value of start_datetime. For now, let’s use a simple custom method called formatDate which uses the default JavaScript toDateString function.

app/javascript/packs/Event.js:
import React from 'react'

const formatDate = datetime =>
  new Date(datetime).toDateString()

const Event = props => (
  <div className="event">
    <h2 className="event-title">{props.event.title}</h2>
    <div className="event-datetime">{formatDate(props.event.start_datetime)}</div>
    <div className="event-location">{props.event.location}</div>
  </div>
)

Later on, we’ll use a third-party library like Moment.js to format our dates.

One final change we can do is to use the event ids as keys for the list of events.

app/javascript/packs/EventsList.js:
const EventsList = props => (
  <div>
    {props.events.map(function(event){
      return(
        <Event key={event.id} event={event} />
      )
    })}
  </div>
)