My Takeaway from Reading When

When: The scientific Secrets of Perfect Timing

Book: When: The Scientific Secrets of Perfect Timing
Author: Daniel H. Pink

Any book that promotes napping is a win for me. These days it’s easy for me to catch a couple ZZZs as I work from home. When I was an employee or working at a clients site I would sometimes have an “errand” to run in the afternoon. An “errand” that involved driving to secluded place, tilting the seat back, and inspecting the inside of my eyelids for 20 minutes.

Aside from taking more naps my main takeaway from this book is to force start, middle, and ends. At least the good parts of starting, ending, and reaching the half-way points. You know, the old advice about breaking up a long project or task into smaller bits. Not something I didn’t already know but still good to be reminded of.

When also brought up the importance of the middle. Not just middle life but also the middle of a project or a task. Acknowledging the middle could be useful when you are stuck but it does not make sense to force and end/start. According to When most of the work on task gets done after the halfway mark and this holds true for short or long tasks.

Finally the last thing from When I’ll try to incorporate into my life is starting something important on good start days. Days like the start of the month, start of the week, after a holiday, anniversary of a life event, etc.

Posted in Takeaways | Tagged , | Comments Off on My Takeaway from Reading When

Thank you for Attending my SQL Saturday 840 Presentation – Create a Time Travelling Database

Thank you to everyone who attended my SQL Saturday 840Create a Time Travelling Database” presentation. I enjoyed your questions and the discussion after the presentation.

If you have any further questions feel free to reach out to me at chris.cumming@saturdaymp.com or @saturdaymp. I can also be found on the DevEdmonton and Legacy Code Rocks Slack channels.

Multiple Timelines

More resources about temporal databases:

P.S. – It was toss up between the below song and Rocky Horror Picture Show Time Warp. Guess I’m in a melancholy mood on this snowy day. Yes it is snowing on April 30th in Edmonton.

But there never seems to be enough time
To do the things you want to do, once you find them
I’ve looked around enough to know
That you’re the one I want to go through time with

Posted in Uncategorized | Comments Off on Thank you for Attending my SQL Saturday 840 Presentation – Create a Time Travelling Database

Introduction to ORMs for DBAs: Part 7 – Create GamePlayers Table

I gave the Introduction to ORMs for DBAs presentation at SQL Saturday 710 but it didn’t go as well as I would have liked (i.e. I had trouble getting my demo working).  Since the demo didn’t work live I thought I would show you what was supposed to happen during the demo.  You can find the slides I showed before the demo here.

The goal of this demo is create a basic website that tracks the games you and your friends play and display wins and losses on the home page.  I used a MacBook Pro for my presentation so you will see Mac screen shots.  That said the demo will also work on Windows.

In the previous post we created the GamesPlayed table and CRUD methods.  The GamesPlayed table stores when a game was played but it does not store who played the game.  In this post we will create the GamePlayers table to store who played the game and, more importantly, who won.

If you skipped the previous post but want to follow along open up 07-Create Game Players Table. Then run the migrations to create the Player, Games, GameResultTypes, and GamesPlayed tables in the database.  Your database similar to the below screen shot.  The migration IDs can be different but the tables should exist.

In this post we will create the last table the GamePlayers. It’s the table that tracks which players where involved with a game and if they won or loss.

Game Tracker ERD

As usual we start with the model. The only thing different about this model is it joins three other tables so had three foreign keys. Remember to add a foreign key in Entity Framework you add the ID and the Class.

using System.ComponentModel.DataAnnotations.Schema;

namespace SaturdayMP.GameTracker.Models
{
    [Table("GamePlayers")]
    public class GamePlayer
    {
        public int Id { get; set; }

        public int GamePlayedId { get; set; }
        public GamePlayed GamePlayed { get; set; }

        public int PlayerId { get; set; }
        public Player Player { get; set; }

        public int GameResultTypeId { get; set; }
        public GameResultType GameResultType { get; set; }
    }
}

You also need to add the other side the foreign key to the existing models. First the GamePlayed model:

public ICollection<GamePlayer> GamePlayers { get; set; }

Then the Game model:

public ICollection<GamePlayed> GamesPlayed { get; set; }

Finally the GameResultType model: ….Actually we won’t add the reference relationship to the GameResultType. This is to prevent a common mistake with ORMs where we accidentally load a bunch of records.

Say we did add the GameResultType->GamePlayer then in our code called that relationship:

myGamePlayed.GamesPlayed.Count

The above would load all the games played for the given type. Not a problem when your application is young and you only have a couple of games played. What happens when you have hundred or thousands of games played? Then it becomes a problem.

When we do need to filter by the game results, such as who won, we would write it from the perspective of the player. For example:

var wins = _context.Players
  .Where(p =&gt; p.Id == 1)
  .Select(p =&gt; new
  {
    PlayerName = p.Name,
    Wins = p.GamesPlayers.Where(gp => gp.GameResultType.KeyCode == 10).Count(),
  })
  .First();

With that out of the way, let us get back to coding and add the new model to the context:

public DbSet<GamePlayer> GamePlayers { get; set; }

Now that the models are setup we can create the migration:

dotnet ef migrations add CreateGamePlayersTable

Check the migration file to make sure it looks reasonable:

Now that the migration exists and looks correct we can run the migration on the database. Once the migration is complete you should be view the new GamePlayers table in the database.

dotnet ef database update

Good work. That was our most complicated table yet. This seems like a good time to stop and take a break. In the next post we will create the Game Players CRUD methods.

If you got stuck you can find completed Part 7 here.  If you have any questions or spot an issue in the code I would prefer if you opened a issue in GitHub but you can e-mail (chris.cumming@saturdaymp.com) me as well.

Posted in Code Examples, Introduction to ORMs for DBAs, Software Development | Tagged , , , , , , | Comments Off on Introduction to ORMs for DBAs: Part 7 – Create GamePlayers Table

My Takeaway from Moneyball

Moneyball cover.

Book: Moneyball: The Art Of Winning An Unfair Game
Author: Michael Lewis

Both the movie and book are great and truth be told I watched the movie well before reading the book. In both cases they do a great job of showing how statics can find undervalued baseball players. Lots of time spent focusing on what stats actually win baseball games such as the famous “he gets on base” quote.

However, that was not my takeaway from reading this book. I already know I should take actions that, statistically speaking, maximize my chances of a positive outcome. The problem is that is easier said then done. Statics only work if you are consistent over time and emotions are not consistent.

So my takeaway from Moneyball is more a reminder. Don’t let emotions derail my long term plans. Stick with actions that, statically speaking, that are likely to lead to positive outcomes and minimize negative outcomes. Don’t let one negative outcome derail my long term plan. Play the long game.

Posted in Takeaways | Tagged , | Comments Off on My Takeaway from Moneyball

Today I Learned How to Create a React-Rails App

A working example can be found here in the Saturday MP Examples GitHub.

First thing you need to do is create a basic Rails app as outlined in my previous post.  My setup is the same as creating Rails app: Ubuntu 18.04 LTS host using Docker to containerize my development environment.

Once your basic Rails app is up and running you can add React.  This example uses React-Rails.  First, you need to update the Docker file to install Node JS and Yarn.  Open up the DockerFile and change it so it looks like the below.

FROM ruby:2.5.3

# To install a later version of Node JS and Yarn.
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

# Install the needed software.
RUN apt-get update -qq &amp;amp;&amp;amp; apt-get install -y build-essential libpq-dev nodejs yarn

# Create the website folder and map the Gemfiles.
RUN mkdir /website
WORKDIR /website
COPY Gemfile /website/Gemfile
COPY Gemfile.lock /website/Gemfile.lock

# Update the bundler then install the gems.
RUN gem install bundler
RUN bundle install

# Copy our files to the website.
COPY . /website
Changes to Docker file.

Actually only the top of the file is changed, the bottom is the same just with better layout and comments.  The top we add a reference to the Node and Yarn repositories then added nodejs and yarn to the install list.

Next add the required Gems: webpacker and react-rails:

# React
gem 'webpacker'
gem 'react-rails'

Now that the Docker and Gemfile is updated we can rebuild the container:

docker-compose build web
Rebuilding the Docker container with Node and Yarn.

A couple final steps.  Run the newly build container and run the following commands:

docker-compose run web bash

rails webpacker:install
rails webpacker:install:react
rails g react:install
Installing Webpacker.
Installing Webpacker React.
Generating react.

The Rails app should be React ready.  To smoke test we need a view and controller.  If you already have a page in your app you can skip this step.

Generate the home controller by executing the following:

rails g controller Home index

Generate home controller and view.

Then generate a basic React component:

rails g react:component HelloWorld greeting:string
Generate React Hello World component.

Then add the following line to the application layout file:

<%= javascript_pack_tag 'application' %>
Add React application to layout.

Finally add the following line to the home view:

<%= react_component("HelloWorld", { greeting: "Hello from react-rails." }) %>
Add React component to Home page.

Now run the add and navigate to the http://localhost:3000/home/index and you should see the React message:

Greetings from React message.
In

In memory of Walk of the Earth’s Beard Guy I present one my favourite songs Walk of the Earth songs:

You gotta hold on to what you got, babe
It ain’t always greener on the other side, you know
We ain’t rich but we’re worth a lot, babe
I wanna see the world with your hand in mine, you know

Posted in Code Examples, Software Development, Today I Learned | Tagged , | Comments Off on Today I Learned How to Create a React-Rails App

Happy Holidays!

Saturday MP (i.e. Chris and Ada) are taking some time off over the holidays to visit with family, friends, and spending a day not changing out of our pyjamas and playing games all day.  We will be back to our regularly scheduled programming on January 2nd, 2019.

Happy holidays and all the best in 2019!

Old Timey Record Player

P.S. – My daughter wanted a record player for Christmas.  I know, everything old is new again.  Lucky for my daughter she got the above old timey looking record player as an early Christmas gift when her Aunt and family where visiting this weekend.  Not only does it play records but is also plays tapes, CDs, radio, and Bluetooth.  Now we just need to get some records.

In honour of the great gift I present my daughters 2nd favourite Christmas song.

Posted in Fun | Tagged | Comments Off on Happy Holidays!

Today I Learned how to Generate a ERD for Rails Application

Back in the day Rails apps didn’t add foreign keys to database tables.  Believe it or not this was a feature not a bug.  The idea was that you shouldn’t “repeat” the relationship between you models in the code and in the database.  It wasn’t until Rails 4.2 that support was added for foreign keys.  

As you can probably guess I think this was a mistake.  If you have worked with a database without any foreign key constraints you quickly run into data integrity issues.  I don’t care how careful you think you are you will eventually screw up.  If not you then another person or application will corrupt your data.  Line items not attached to an order, address without customers, cats and dogs living together, etc.

It’s also harder to use tools on a database without foreign keys.  Reporting tools often relay on foreign keys to help the user create queries and display data.

Finally without foreign keys it’s hard to see how tables are related to each other.  You can’t just generate a ERD.  While you can, but you end up with just a bunch of tables with no idea how they are related to each other.  This is the problem I’m currently having with a database for a Rails 3.2 application.  How can see the relationships between the tables?

What I need is a tool that can read the relationships between the models in the application.  Lucky for me this tool exists and is called Rails-ERD.

You can find the install instructions here.  In my case I had a Rails 3.2 application running in a Docker container but that was client code that I can’t show here.  Instead my example will be the Saturday MP website which is Rails 4 with foreign keys but will work fine for this example. 

My website also uses Docker.  If you don’t use Docker then just run the commands on you local machine.  First step is to update the Dockerfile to install Graphviz.

Then add the rails-erd gem to the Gemfile.  Just add it to development as we don’t need it for tests and production.

Then rebuild the container to install Graphviz and the Rails-ERD gem.

Since we are using Docker we first need to spin up our container then ran the rake command to create the ERD.

docker-compose run web bash up

rake erd

This will create a PDF version of your ERD.  If you have a small ERD, like my website, then you are done. 

If you have a larger ERD, like the client code I can’t show you, then you are not done as the ERD will be unreadably small if you print it.  Printing things is something old men with bad eyes like to do.  What you can do is break up the database into sections.  For example, we could just show the product part of my database with the following command:

rake erd filename="products_erd" title="Saturday MP Products ERD" only="Product,ProductVersion"

What I like to do is create a batch file that will generate all the ERDs and but it in the databases folder.  Then you can run this batch file whenever you update the database to generate updated ERDs.

#!/usr/bin/env bash
rake erd filename="erd" title="Saturday MP ERD"
rake erd filename="products_erd" title="Saturday MP Products ERD" only="Product,ProductVersion"

Thanks for Voormedia for creating Rails-ERD and sharing it.

P.S. – About a month ago we saw The Once live and they sang the below song.  Actually, they got the the audience to sing the “By the glow of the kerosene light” part.  Weirdly it got really dusty in the theater at the end of the song because everyones eyes where watery, including the bands.

And sometimes love bloomed and sometimes dreams die
By the glow of the kerosene light.

By the glow of the kerosene light.

Posted in Code Examples, Software Development, Today I Learned | Tagged , , , | Comments Off on Today I Learned how to Generate a ERD for Rails Application

Introduction to ORMs for DBAs: Part 6 – Create GamesPlayed Table and CRUD

I gave the Introduction to ORMs for DBAs presentation at SQL Saturday 710 but it didn’t go as well as I would have liked (i.e. I had trouble getting my demo working).  Since the demo didn’t work live I thought I would show you what was supposed to happen during the demo.  You can find the slides I showed before the demo here.

The goal of this demo is create a basic website that tracks the games you and your friends play and display wins and losses on the home page.  I used a MacBook Pro for my presentation so you will see Mac screen shots.  That said the demo will also work on Windows.

In the previous post we created the Games Results Type table and CRUD methods.  This table stores the possible outcomes of a game (i.e. win, lose, or tie).  In this post we will create the Game Played Table and CRUD.  This table tracks when a game was played but does not track who played the game.  More on that later.

If you skipped the previous post but want to follow along open up 06 – Create GamesPlayed Table and CRUD.  Then run the migrations to create the Player, Games, and GameResultTypes tables in the database.  Your database similar to the below screen shot.  The migration IDs can be different but the tables should exist.

Part 6 Initial Database

After completing Part 5 our database has the edge tables completed (Players, Games, and GameResultTypes) but none of the central tables (GamesPlayed and GamePlayers).  Lets start with our second most important edge table, the GamesPlayed table.

Game Tracker ERD

As usual we will start by creating the model.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace SaturdayMP.GameTracker.Models
{
    [Table("GamesPlayed")]
    public class GamePlayed
    {
        public int Id { get; set; }

        public int GameId { get; set; }
        public Game Game { get; set; }

        public DateTime DatePlayed { get; set; }
    }
}

This should look similar to the other models we have created so far with one minor difference.  This model is part of a one-to-many relationship with the Games table.  One game can be played many times. 

The below line is what links our new model to the Games table.  It says a GamesPlayed record belongs to a Game record.

public int GameId { get; set; }
public Game Game { get; set; }

Entity Framework, and most other ORMs, are smart enough to correctly map a reference to another model as a foreign key.

This relationship goes both ways and the relationship needs to be added to the Games table as well.  In this case it says a Game record can have many GamesPlayed records which is why a list is used.

public ICollection<GamePlayed> GamesPlayed { get; set; }

With the model created lets generate the migration.  This command should be familiar by now if you have been following along since the beginning.

dotnet ef migrations add CreateGamesPlayedTable

Checking the created migration we can see the foreign key created.

Run the migration on the database to create the new table.

dotnet ef database update

Next lets create the CRUD.

dotnet aspnet-codegenerator controller -name GamesPlayedController -outDir Controllers -m GamePlayed -dc GameTrackerContext -udl

Remember if the files don’t appear in the solution you might need to close the solution and re-open it.

To see our new CRUD methods we need to add the menu item to Layout.cshtml file.

<li><a asp-area="" asp-controller="GamesPlayed" asp-action="Index">Games Played</a></li>

Add Games Played Menu to Layout

Now lets run the application and navigate to the Games Played page.  Assuming you have a couple games created you should see something similar to the below.  If you don’t have any Games created, go to Games page first and add a couple.

Games Played Page with Game ID

Notice that the Game is linked to the Game ID?  That is not very user friendly.  We should show the name of the game instead. 

Lets start with the Index page.  Open up the page can change the following line so it references the name of the game instead of the ID. 

NOTE: you don’t need to stop running the application.  After your change you can just reload the page in your browser and see you changes.  Just make sure you have saved your changes you might have to hold down the Shift key when reloading the browser.

@Html.DisplayFor(modelItem => item.Game.Name)

That looks better.  Next up the Create page.  If we open up the view we don’t see a reference to the GamesPlayed object.  Instead we see a ViewBag.  This ViewBag contains a list of Games that we want to populate the dropdown with.

To show the game name in the create view we need to make changes to the controller.  Open up the GamesPlayedController and find the Get Create method.  Notice the creation of the ViewData?  ViewData and ViewBag are just different way of referencing the same data.  For some reason the Microsoft scaffolding decided to not be consistent.

The SelectList method is helper method to generate a list of data for populating a dropdown.  It takes a list of objects and what field you want to use as the key (DataValueField) and what field to display (DataTextField) to the user.  Currently the ID field is used as both the data and text fields.  To show the game name change the DataTextField argument, the 2nd one, to “Name”.

When you make changes to the controller you have to restart your application.  You can’t just reload the we page like we did when we made changes to the view.

Restart the application and create a new game played and it should now show the name of the game instead of the ID.

There are 3 more views that need to fixed: Details, Edit, and Delete.  In all cases the changes are similar to the ones we have done above.

To fix the Games Played Details update the view.  Change the Game.Id to Game.Name.

For the edit we need to update the SelectList to show the name but we have to do this in two spots.  The first is the Get and the second is the Post methods of Edit.

Finally we need to update the Delete page to show the name by updating view:

The Games Played section is now complete.  In the next post we will create the Game Players table.  This table will be the most complicated table so we will just create the table and save the CRUD for later.  It should also result in a smaller blog post.

If you got stuck you can find completed Part 6 here.  If you have any questions or spot an issue in the code I would prefer if you opened a issue in GitHub but you can e-mail (chris.cumming@saturdaymp.com) me as well.

Posted in Code Examples, Introduction to ORMs for DBAs, Software Development | Tagged , , , , , , | Comments Off on Introduction to ORMs for DBAs: Part 6 – Create GamesPlayed Table and CRUD

Introduction to ORMs for DBAs: Part 5 – Create GameResultTypes Table and CRUD

I gave the Introduction to ORMs for DBAs presentation at SQL Saturday 710 but it didn’t go as well as I would have liked (i.e. I had trouble getting my demo working).  Since the demo didn’t work live I thought I would show you what was supposed to happen during the demo.  You can find the slides I showed before the demo here.

The goal of this demo is create a basic website that tracks the games you and your friends play and display wins and losses on the home page.  I used a MacBook Pro for my presentation so you will see Mac screen shots.  That said the demo will also work on Windows.

In the previous post we created the Games CRUD and the post before that we created the Games table.  In this post we will create both the GameResultTypes table CRUD methods. 

If you skipped the previous post but want to follow along open up 05 – Create GameResults Table.  Then run the migrations to create the Players and Games table in the database so your database similar to the below screen shot.  The migration IDs can be different but the tables should exist.

Player and Games Table Exist

Now that we can store tables and players we can start thinking about how to store the games our players have played.  When a game is played we need to store the game that was played, who played in the game, and who won.  A first draft for our data model might look like:

Game Tracker ERD Without GameResultTypes

Actually we can’t just track who won as there are three possible outcomes for a game: win, loss, and tie.  Depending on the game it’s possible to have multiple winners, losers, and ties.  For example, a cooperative game like Sentinels of the Multiverse either everyone wins or everyone loses.

We need a table that can track if a player lost, won, or tied a game.  A type table for the results of a game.  Our new data model looks like:

Game Tracker ERD Without GameResultTypes KeyCode

One problem developers and report writers have with type tables is determine what record stands for what type.  For example, what record in the GameResultTypes represents a Win?  How would you query for all the games a player won?

One possible way is to query on the string column:

Select *
From GamesPlayed gp
Inner Join GameResultTypes grt On gp.GameResultTypeId = grt.Id
Where gp.PlayerId = #
And grt.Type = 'Won'

This is a bad idea as the text could change.  How about the ID?

Select *
From GamesPlayed gp
Inner Join GameResultTypes grt On gp.GameResultTypeId = grt.Id
Where gp.PlayerId = #
And grt.ID = 10

Using an auto-increment ID as the identifier is a bad idea as it is set by the database and can change.  This is especially problematic as the database is migrated between environments such as from test to production.

How about not auto-incrementing the ID field?  That would work but I’m not a fan.  I prefer all the ID columns in my database to consistent.  I also prefer not to hard code IDs.  It should be up to the database to decide what the ID value is.  The only time I reference an ID is after I’ve retrieved the record via a non-ID search.

My preference is to have a field called KeyCode.  This is a unique integer field with a value that is set when the record is entered and never changed.  It can then be used whenever you need to access that particular type.  For example, if we assign the Win Game Result Type a Key Code of 10 then we can find all the games a player won by:

Select *
From GamesPlayed gp
Inner Join GameResultTypes grt On gp.GameResultTypeId = grt.Id
Where gp.PlayerId = #
And grt.KeyCode = 10

That means our GameResultTypes table now looks like:

Game Tracker ERD

Lets create a Game Result Type model for what we have so far.

using System.ComponentModel.DataAnnotations;

namespace SaturdayMP.GameTracker.Models
{
  public class GameResultType
  {
    public int Id { get; set; }

    public int KeyCode { get; set; }

    [MaxLength(10)]
    public string Type { get; set; }
  }
}

Initial Game Result Type Model

Another common feature of type table is we sometimes know all the records they will contain.  In this case they will only contain win, lose, and tie.

In software if we have a set amount of known types we can wrap them in an enum.  At it’s core an enum is really an integer but it only allows certain values.  For example, we can have colour enum that only allows certain colours:

public enum Colors
{
  Red,
  Blue,
  Green
}

Lets create an enum for our game result types in our model.  We could put in a seperate file but in this case the enum only exists because of the GameResultTypes so lets add it in the same file.

public enum GameResultTypes
{
Win = 10,
Loss = 11,
Tie = 12
}

Game Result Type Model with Enum

If we don’t assign numbers to the enums they will be auto assigned.  In this case the enums will be set to the KeyCode field so we want to know what these values are.

Now that we have the enum lets update our model with some syntatic sugar to make it easier to work with the enums.

using System.ComponentModel.DataAnnotations;

namespace SaturdayMP.GameTracker.Models
{
  public enum GameResultTypeEnums
  {
    Win = 10,
    Loss = 11,
    Tie = 12
  }

  public class GameResultType
  {
    public GameResultType()
    {
    }

  public GameResultType(GameResultTypeEnums @enum)
  {
    KeyCode = (int)@enum;
    Type = @enum.ToString();
  }

  public int Id { get; set; }

  public int KeyCode { get; set; }

  [MaxLength(10)]
  public string Type { get; set; }

  public static implicit operator GameResultType(GameResultTypeEnums @enum) =&amp;amp;gt; new GameResultType(@enum);

  public static implicit operator GameResultTypeEnums(GameResultType gameResultType) =&amp;amp;gt; (GameResultTypeEnums)gameResultType.Id;
  }
}

Complete Game Result Types Model

Notice that we still have the KeyCode field as a integer.  Some ORMs allow you to use enums but currently Entity Framework Core does not allow this.

The couple lines at the bottom simplify the conversion of the GameResultTypeEnums to the GameResultType object so we can write something like:

// Convert enum to model object.
GameResultType gameResultObject = GameResultTypeEnums.Win;

// Convert model object to enum.
GameResultTypeEnums gameResultTypeEnum = gameResultObject;

Now that the model is complete we can create the actual table in the database using this now familiar commands to create the migration:

dotnet ef migrations add CreateGameResultTypesTable

Create Game Result Types Migration
Game Result Type Migration

Then apply the migration:

dotnet ef database update

Update Database with Game Result Types Table
GameResultTypes Table in Database

Since we know that this table will only hold 3 records and we know what they are lets seed them.  To do this create a new class in the Data folder and call it DbInitializer.  In our new class create the Initialize method that will seed the data.

using System;
using System.Linq;
using SaturdayMP.GameTracker.Models;

namespace SaturdayMP.GameTracker.Data
{
  public static class DbInitializer
  {

    public static void Initialize(GameTrackerContext context)
    {
      if (context.GameResultTypes.Any())
      {
        // DB has already been seeded.
        return;
      }

      // Seed the Game Type Enums.
      foreach(GameResultTypeEnums result in Enum.GetValues(typeof(GameResultTypeEnums)))
      {
        context.Add&amp;lt;GameResultType&amp;gt;(result);
        context.SaveChanges();
      }

    }
  }
}

DbInitializer Class

The first if statement checks if the data has already been seeded.  If it has, then don’t seed it again.  The second part loops over all the GameResultTypeEnums and creates a record in the database.

Now we need to call our DbInitializer.  Lets do this when our application starts up in the Main:

var context = services.GetRequiredService&lt;SaturdayMP.GameTracker.Data.GameTrackerContext&gt;();
DbInitializer.Initialize(context);

Initialize Database in Main

Now if you start the application the GameResultTypes table will be populated.

GameResultTypes Table in Database

Notice that we don’t have any screens to edit GameResultTypes.  Lets stop the application and add our CRUD methods. Again this command should now be familiar:

dotnet aspnet-codegenerator controller -name GameResultsTypeController -outDir Controllers -m GameResultType -dc GameTrackerContext -udl

Command to Add Game Result Type CRUD

Unlike the other tables we have created we want to limit the actions that can be done to the GameResultTypes table.  Since we know it should only have 3 records which are seeded when the application is started we don’t need the Insert or Delete controller methods.  Lets remove them:

Delete Game Result Controller Create Method
Delete Game Result Controller Delete Method

We also need to remove the views for these methods:

Delete Game Results Type Create and Delete Views

Finally lets change the Edit view so the user can only change the description of the type.  The user shouldn’t be able to change the KeyCode.  The quickest way to do this is make the input control for the KeyCode to be read-only in the Edit view:

Make KeyCode ReadOnly in Edit View

Finally lets add a menu item so we can easily get to the Game Results Type pages:

Adding Game Result Types Menu

Run the application and you should be able to edit just the text of the game results:

Game Results Index
Game Results Edit

In the next post we will create the Games Played table and CRUD methods.  This is one of the the central tables of the application, second only to the Game Players table.

If you got stuck you can find completed Part 5 here.  If you have any questions or spot an issue in the code I would prefer if you opened a issue in GitHub but you can e-mail (chris.cumming@saturdaymp.com) me as well.

Posted in Code Examples, Introduction to ORMs for DBAs, Software Development | Tagged , , , , , , | Comments Off on Introduction to ORMs for DBAs: Part 5 – Create GameResultTypes Table and CRUD

Today I Learned how to Create Rails Docker Container Without Ruby Installed

I was curious to see if I could create a Docker container for a new Rails project without having Ruby or Rails installed on the host machine.  To do this I created a new Ubuntu 18 virtual machine with the bare minimum installed for the OS.  I also install Docker, RubyMine, and DataGrip.

Initially I was hoping I could just create the new project inside RubyMine.  Unfortunately I couldn’t get it working.  As you will see setting up the initial Docker container requires more then just running the “docker-compose up” command.

My main resource in setting up the image was Docker Rails Quickstart Guide.   The basic plan is:

  1. Setup Ruby Docker container.
  2. Add default Gemfile for Rails.  Required to create new Rails application.
  3. Create a new Rails application but don’t build the container yet.
  4. Update the configuration files.
  5. Build the docker container to install the Gems.

I started off as they recommended and created an empty folder with Dockerfile.

FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /website
WORKDIR /website
COPY Gemfile /website/Gemfile
COPY Gemfile.lock /website/Gemfile.lock
RUN gem install bundler
RUN bundle install
COPY . /website

Dockerfile for Rails Container

I then created a basic Gemfile and empty Gemfile.lock file.

source 'https://rubygems.org'
gem 'rails', '5.2.0'

Initial Gemfile

Finally I created the docker-compose file.

You might have noticed this file is a bit different then the one in the Docker Quickstart.  I made these changes after the contain failed to build and/or I couldn’t connect to it with RubyMine.

version: '2'
services:
  db:
    image: postgres
    ports:
      - "5432:5432"
    environment:
      POSTGRES_PASSWORD: password1234
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/website
    ports:
      - "3000:3000"
    depends_on:
      - db

Docker Compose

The first change I made was downgrading the version from 3 to 2 as RubyMine currently only supports 2.  I also added ports and a password for the Postgres database so I can access from DataGrip.  If you don’t set the port and password your Rails application will be able to access the database but nothing else will.

I then created the rails application as recommended by the quickstart guide.  Since this is the first time running it pulls down the docker files.  Then I ran into the first of many permission errors.

docker-compose run web rails new . --force --database=postgresql

Creating new Rails App Cmd

First Permission Error

This permission error was caused by the Postgres container.  The files created Docker images are usually owned by root but some of the temporary Postgres files where also owned by VBoxAdd.

Database File Owned by VBoxAdd

After a while I figured out the way to fix this was to run the following command:

sudo chown -R $USER:$USER .

I got several permission errors during my trails and error of setting up the Rails container.  Every time I would just run the above command to fix it.

Once the permission errors went away I was able to create a new rails application.  Before the files for the new rails application where created it needs to build the Docker container so don’t be surprised to see the below.

Building Rails Container

Your newly created rails files might be owned by root.  In this case run the command you have probably become very familiar with:

sudo chown -R $USER:$USER .

Notice that the Gemfile has been updated and populated with all the Gems needed to run a new rails application.

Gemfile Populated by Rails New

Since we just called run on the web Docker container non of the installed Gems where saved in the container.  To prevent having to re-install the gems every time the container is run we need to build it.

Build Containers

Now the web container is ready but our database isn’t.  Open up the database config file and set the host, username, and password.

Database Config File Settings

Now create the Rails databases.

docker-compose run web rake db:create

Create the Rails Databases

Again if you get permission errors trying to create the databases run change permissions command.

sudo chown -R $USER:$USER .

Now bring up the containers and you should be see the Welcome to Rails website.

docker-compose up

Docker Compose Up

Yay Your are on Rails

The site is working but now we need to get it working with RubyMine.  If you use a different editor then your steps might be different.

First stop the containers using Ctrl-C.

Stopping Containers

To safe us some steps later lets update the Gemfile.  By default Rails installs the Byebug gem for debugging.  RubyMine likes the Ruby Debug IDE gem.  Just don’t run them both at the same time as they don’t play well together.

Remove ByeBug from the Gemfile and add Ruby Debug IDE.  Your Gemfile will look like:

Ruby Debug IDE Added to Gemfile

Now rebuild the Docker container so the new gems are installed.

docker-compose build

Then open up RubyMine and open up your project.  Once it’s open we need to tell RubyMine about our Docker containers.  To this go to File–>Settings.  Then go the Build, Execution, Deployment–>Docker in the Settings dialog and make sure Docker is setup correctly.  If it is you should see something similar to the below.

Docker Settings

Docker Settings Registry

You might be missing Docker Machine in which case you can install it following these instructions.  Try re-opening RubyMine and if it still does not find Docker Machine then you will need to tell it the exact path.

Now that Docker is setup correctly in RubyMine we need to setup the Ruby SDK by going to Languages & Frameworks –> Ruby  SDK and Gems in the Settings dialog.  Assuming you don’t have Ruby installed on your local workstation the list of Ruby SDKs should be empty.  Click the green plus sign to add one and choose New Remote.

Add New Remote Ruby SDK in RubyMine

In the Configure Remote Ruby Interpreter select Docker Compose and enter in the settings shown below.  This tells RubyMine what Docker Compose file to use to build the containers and container is the website.

Configure Remote Ruby Interpreter Dialog

After you click OK RubyMine will run the Docker containers and attempt to find Ruby in the container.  It will also attempt to find all the gems installed on the container.  This can take a couple minutes but if everything works correctly you should see something like:

Remote Docker Compose Ruby SDK Correctly Configured

Sometime the correct Ruby version will be listed by the gems won’t be shown.  To fix you might have to remove the newly added Ruby SDK by clicking the minus sign and try again.

If RubyMine can’t load the Docker containers then it will probably display a very unhelpful error message.  Try going back to the terminal and running docker-compose up manually.  If you get any errors fix them then try configuring RubyMine again.

Assuming everything is working correctly you should be able to run and debug the application.  To test that debugging works put a break point then try debugging.

Application Breakpoint

Run Debug Development

Application Breakpoint Hit

Now you can develop your new app without installing Ruby or Rails on your local workstation.  If you have any tips for dealing with the Docker Prostgres permission issues let me know at chris.cumming@saturdaymp.com.

P.S. – My wife recently introduced me to the band Walk of the Earth which we get to see live shortly.  They are most famous for all the band members covering Gotye’s “Somebody That I used Know” a single guitar but my favourite song is an original called “Rule the World“.

They said no way
I say I rule the world
(Ain’t afraid of the walls, I’mma break them down)
They stay the same
Well, I’m feelin’ high as a bird
(Ain’t afraid of the ground, I’mma stand up)

Posted in Code Examples, Software Development, Today I Learned | Tagged , , , , | Comments Off on Today I Learned how to Create Rails Docker Container Without Ruby Installed