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.
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> )