Warning: This checklist uses a happy path model, meaning it does not rely on TDD to build up the rails app. Additionally, it uses names of routes, models, controllers, and views in code snippets, so make sure to replace those names with the names of those things in your project. Most references are from
https://backend.turing.io/module2/misc/blogger
- Create Rails Application
- From the command line, start a new rails app. For example,
rails new blogger -T -d="postgresql" --skip-spring --skip-turbolinks
- Environment Setup
- Install all necessary gems in Gemfile under
group :development, :test do. For example,gem 'pry' gem 'rspec-rails', '~> 4.0.1' gem 'capybara' gem 'launchy' gem 'simplecov' gem 'shoulda-matchers', '~> 3.1' gem 'orderly' gem 'active_designer'
- Run the following command in the terminal to install RSpec run:
rails g rspec:install - Add the following simplecov configuration code at the top of the
/spec/rails-helper.rbfilerequire 'simplecov' SimpleCov.start
- Add the following shoulda-matchers configuration code into the
/spec/rails-helper.rbfileShoulda::Matchers.configure do |config| config.integrate do |with| with.test_framework :rspec with.library :rails end end
- It might looks like you have one too many
ends if you put it near the finalendof the file, but that is only a result of the indenting the file has when it is automatically generated.
- It might looks like you have one too many
- From the command line run:
bundle update - From the command line run:
bundle install
- Create Database and Resources
-
To create the database in the terminal run:
rails db:create -
To generate resources in the terminal run
- For no relationship, for example,
rails generate migration CreateArticles title:string body:text- For a belongs to relationship, for example,
rails generate migration CreateComments author_name:string body:text article:references- For a many-to-many relationship, for example,
rails generate migration CreateTaggings tag:references article:references- Note that the join for the many-to-many relationship cannot be generated unless both sides of the many-to-many relationship have been previously generated. Rails will complain it does not know about any underlying many- to-many table that does not yet exist if the underlying tables haven't been created.
-
Check the migration that was generated to make sure the table is being created properly and to add timestamps
t.timestamps
-
After a migration is successfully generated, run
rails db:migratein the terminal. -
One-to-Many
- Create a model by creating a model file in
app/models/, for exampleapp/models/comment.rb. For example the belongs to side of the relationship,class Comment < ApplicationRecord belongs_to :article end
- Create a model by creating a model file in
app/models/, for exampleapp/models/article.rb. For example the many side of the relationship,class Article < ActiveRecord::Base has_many :comments end
- Create a test by creating a file in
spec/models/, for the belongs to side of the relationship, for examplespec/models/comment_spec.rb. For example,require "rails_helper" describe Comment, type: :model do describe "relationships" do it {should belong_to(:article)} end end
- Create a test by creating a file in
spec/models/, for the many side of the relationship, for example
spec/models/article_spec.rb. For example,require "rails_helper" describe Article, type: :model do describe "validations" do it {should have_many(:comments)} end end
- Create a model by creating a model file in
-
Many-to-Many
- When referring to a camel cased table with multiple words, for example
SongArtists, in a test or model, use snake case, for examplesong_artists. - Create a model in
app/models/, for example,app/models/tag.rb, or add code if it has already been created for each side of the many-to-many relationship. Make sure to do this for each of the many-to-many models. For example the many side of the relationship,class Tag < ApplicationRecord has_many :taggings has_many :articles, through: :taggings end
- Create a join model in
app/models/, for example,app/models/tagging.rb. For example the join model,class Tagging < ApplicationRecord belongs_to :tag belongs_to :article end
- Create a test for each many side of the relationship, for example,
spec/models/tag_spec.rb. For example,require "rails_helper" describe Tag, type: :model do describe "relationships" do it {should have_many(:tagings)} it {should have_many(:articles).through(:taggings)} end end
- Create a test for the joins, for example,
spec/models/tagging_spec.rb. For example,require "rails_helper" describe Tagging, type: :model do describe "relationships" do it {should belong_to(:tag)} it {should belong_to(:article)} end end
- When referring to a camel cased table with multiple words, for example
-
Relationships
- One-to-Many
- The objects on the "many" end should have a foreign key referencing the "one" object.
- Objects on the "many" end "belong_to" the object on the "one" end. For example, "an article has_many comments and a comment belongs_to an article"
- Many-to-Many
- The joins table should have a foreign key referencing each of the many tables.
- Testing
- Create both a
modelsandfeaturessub-directory in thespecfolder. - Framework for a model test,
require "rails_helper" describe Article, type: :model do describe "validations" do it {should validate_presence_of(:title)} it {should validate_presence_of(:body)} end end
- Framework for a feature test,
require "rails_helper" RSpec.describe "articles index page", type: :feature do before :each do @article_1 = Article.create!(title: "Title 1", body: "Body 1") @article_2 = Article.create!(title: "Title 2", body: "Body 2") end end describe "user sees all articles" do describe "they visit /articles" do it "displays all articles" do visit '/articles' expect(page).to have_content(article_1.title) expect(page).to have_content(article_2.title) end end end
- Create Routes
- Add code into
/config/routes.rb, such as one of the following examples,resources :articles resources :articles, only: [:index, :show] get "/articles/:id", to: "articles#show"
- Uses snake_case for controller names in the routes if it more than one word. Example,
monster_trucks#showfor a controller namedMonsterTrucksController. - Seven RESTful routes:
index, new, create, show, edit, update, and destoryget '/articles', to: "articles#index=> display a list of all resourcesget '/articles/new', to: "articles#new=> show form to make a new resourcepost '/articles', to: "articles#create"=> add new resource to the database, then redirectget '/articles/:id', to: "articles#show"=> show information about a particular resourceget '/articles/:id/edit', to: "articles#edit"=> show from to edit an existing resourcepatch '/articles/:id', to: "articles#update"=> update an existing resource, then redirectdelete '/articles/:id', to: "articles#destroy"=> delete a particular resource, then redirect
- To display all routes from the command line run
rails routes
- Create Controllers
- Create a controller file in
/app/controllers/, for exampleapp/controllers/articles_controller.rb - Add in the framework for a controller, for example
class ArticlesController < ApplicationController end
- Create Views
- Create directory under
app/viewsnamed after the controller, for example,app/views/articles, and with a file for the view, for example,index.html.erb
- To see a visual representation of all migrated tables run the following commands in the terminal:
active_designer --create db/schema.rbthenopen active_designer/index.html
- For a search
<%= form_with(url: "/search", method: "get") do %> <%= label_tag(:q, "Search for:") %> <%= text_field_tag(:q) %> <%= submit_tag("Search") %> <% end %>
- For a create, using a model
<%= form_with model: Dog.new, local: true do |f| %> <%= f.label :name %> <%= f.text_field :name %> <%= f.label :breed %> <%= f.text_field :breed %> <%= f.label :age %> <%= f.number_field :age %> <%= f.submit %> <% end %>
- Use validates_presence_of in model. For example,
validates_presence_of :title, :body, presence: true
- Use validates_presence_of in model tests. For example,
describe "validations" do it {should validate_presence_of :title} end
- Use path helper with verb if the path helper is ambiguous. For example,
<%= link_to "Delete", article_path(@article), method: :delete %>
- Use at the top of a controller. For example,
before_action :set_article, only: [:show, :destroy, :edit]
- Run generate migration in the terminal. For example,
rails generate migration ChangeBodyToBeTextInComments
- Open migration file and put in change, for example,
change_column :comments, :body, :text
rails db:migrate- Check shcema file that the column data type has changed.
- Run generate migration in the terminal. For example,
rails generate migration AddEmailToComments
- Open migration file and put in change, for example,
add_column :comments, :email, :string
rails db:migrate- Check shcema file that the column data type has changed.