Rails Step By Step “Guide”
Start a new rails project:
Reference: https://github.com/turingschool-examples/task_manager_rails
This will start a new Rails App with postgresql as database and skip the usage of Spring and Turbolinks (method used in task_manager):
rails new task_manager -T -d="postgresql" --skip-spring --skip-turbolinks
Useful testing gems to be added to Gemfile:
group :development, :test do
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'rspec-rails'
gem 'capybara'
gem 'launchy'
gem 'pry'
gem 'simplecov'
gem 'shoulda-matchers'
gem 'orderly'
end
Run bundle and update:
bundle install
bundle update
Add rspec (this will create the spec directory, rails_helper.rb, and spec_helper.rb)
rails g rspec:install
Create app’s database:
rails db:create
If using Shoulda, ensure this is at the bottom of the rails_helper.rb file (within the existing end block)
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end
If using Simplecov, ensure this is at the very top of the rails_helper.rb file
require 'simplecov'
SimpleCov.start
Preferred table creation which adds model and spec directories and files:
rails generate model Table name:string otherfield:string otherfield:string
(make sure to run rails db:migrate after adding a table)
(manually) Add a table with attributes to database (3 separate examples) reference :
rails generate migration CreateArtist title:string genre:string
rails generate migration CreateSong name:string
rails g migration CreatePlaylists name:string
(make sure to run rails db:migrate after adding a table)
Add a column to an existing table:
rails generate migration add_age_to_artists age:string
Remove a column from an existing table:
rails generate migration remove_column :table_name, :column_name
Add default value to pending migration (this is done in the migration file prior to running db:migrate by including default: <default value>:
class AddAgeToArtists < ActiveRecord::Migration
def change
add_column :artists, :age, :string, default: 33
end
end
Create a one-to-many relationship with existing tables (having created artist and song above, we can add Artists to Songs):
rails g migration AddArtistsToSongs artist:references
Create a many-to-many relationship with existing tables via join table:
rails g migration CreatePlaylistSongs song:references playlist:references
Different ways to associate resources to one another (this example is for a one-to-many relationship (Artist has many songs):
artist = Artist.create(name: 'Prince')
song = Song.create(title: 'Raspberry Beret', length: 345, play_count: 34, artist: artist)
OR:
artist = Artist.create(name: 'Prince')
song = Song.create(title: 'Raspberry Beret', length: 345, play_count: 34, artist_id: artist.id)
OR:
artist = Artist.create(name: 'Prince')
song = artist.songs.create(title: 'Raspberry Beret', length: 345, play_count: 34)
Example of relationships syntax in models (in this case a many to many relationship between songs and playlists:
Join Table (PlaylistSongs:
#app/models/playlist_song.rb
class PlaylistSong < ApplicationRecord
belongs_to :playlist
belongs_to :song
end
PlaylistSongs Test:
# spec/models/playlist_song_spec.rb
require 'rails_helper'
RSpec.describe PlaylistSong, type: :model do
describe "relationships" do
it {should belong_to :playlist}
it {should belong_to :song}
end
end
Playlist Model:
#app/models/playlist.rb
class Playlist < ApplicationRecord
has_many :playlist_songs
has_many :songs, through: :playlist_songs
end
Playlist Spec Test:
# spec/models/playlist_spec.rb
require "rails_helper"
RSpec.describe Playlist, type: :model do
describe "relationships" do
it { should have_many :playlist_songs}
it {should have_many(:songs).through(:playlist_songs)}
end
end
Song Model
#app/models/song.rb
class Song < ApplicationRecord
belongs_to :artist
has_many :playlist_songs
has_many :playlists, through: :playlist_songs
end
Song Spec Test:
#spec/models/song_spec.rb
require 'rails_helper'
RSpec.describe Song do
describe 'relationships' do
it {should belong_to :artist}
it {should have_many :playlist_songs}
it {should have_many(:playlists).through(:playlist_songs)}
end
Example of model testing for attributes without validations:
describe 'Attributes' do
it {should allow_value('Tim Robbins').for(:name) }
end