Users and Memes

Now that we have a database, let's put some tables in it. Two things offhand that I can think of that'll be necessary are users and memes. We'll put them on separate tables and connect them together with has and belongs_to syntax.

For now, let's just create the models:

rails generate model User
rails generate model Meme

Model names, and this is important, are singular. Rails does the work of pluralizing things where it's necessary, so let's not fight that.

That command's going to do two things for us. It'll make models in /app/models. They'll be named the same as we indicated above.

We'll also get a few files in /db/migrate. These'll be named with the exact date/time stamp for the moment it was created, plus "_create_XX", where XX is the plural of the model name we indicated. In these files, the methods for creating tables in our database is already started, we just have to add the columns:

class CreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      t.string "first_name"
      t.string "last_name"
      t.string "username"
      t.string "email"
      t.boolean "is_admin"
      t.string "password_digest"
      t.timestamps
    end
    add_index("users", "username")
    add_index("users", "email")
  end
end
class CreateMemes < ActiveRecord::Migration[5.0]
  def change
    create_table :memes do |t|
      t.integer "user_id"
      t.string "name"
      t.string "content_type"
      t.text "content"
      t.timestamps
    end
    add_index("memes", "user_id")
  end
end

Note that Rails was even kind enough to give our tables plural names. It feels a bit like magic, doesn't it?

I added an index on "user_id" in the memes table because I'll want to keep a meme associated with who uploaded it. I added other indices on "username" and "email" in the users table because the Lynda course told me to, but I'm not sure what I'm going to do with those yet.

I also added a few things to the User model (located in /app/models/user.rb).

class User < ApplicationRecord

  has_secure_password

  EMAIL_REGEX = /\A[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}\Z/i

  validates :first_name,  :presence => true
  validates :last_name,   :presence => true
  validates :username,    :presence => true,
                          :uniqueness => true
  validates :email,       :presence => true,
                          :uniqueness => true,
                          :format => EMAIL_REGEX

end

Let's talk about what all that does. 

has_secure_password is a very cool trick that, when combined with un-commenting the bcrypt gem in your Gemfile, allows you to store passwords securely. If you check out the User migration again, you'll see this line:

t.string "password_digest"

That's where the password is going to be stored and encrypted. 

It's great that Rails does so much of this for us.