└── README.md /README.md: -------------------------------------------------------------------------------- 1 | Rails Reference 2 | =============== 3 | 4 | ## Table of Contents 5 | - [Startup Rails App](#startup-rails-app) 6 | - [Gems](#gems) 7 | - [RSpec](#rspec) 8 | - [Factory Girl](#factory-girl) 9 | - [User Authentication](#user-authentication) 10 | - [Show All Routes](#show-all-routes) 11 | - [Make a Model](#make-a-model) 12 | - [Make a Controller](#make-a-controller) 13 | - [Add & Remove Columns from Migrations](#add-column) 14 | - [Resource Routing](#resource-routing) 15 | - [Callbacks & Filters](#callbacks) 16 | - [Heroku Deployment](#heroku-deployment) 17 | 18 | ## Startup Rails App 19 | Do this after forking from master, make sure you're on your own branch. 20 | 21 | 1. cd into your 'project-forks' folder 22 | 2. `echo 'ProjectName' > PROJECTFOLDER/.ruby-gemset` 23 | - ex) `echo 'TaskListRails' > C3Projects--TaskListRails/.ruby-gemset` 24 | 3. `echo '2.2.2' > PROJECTFOLDER/.ruby-version` 25 | - ex) `echo '2.2.2' > C3Projects--TaskListRails/.ruby-version` 26 | 4. cd in to project folder (wrappers happen...) 27 | 5. `rvm gemset list` (yes it's on the gemset we just created) 28 | 6. `gem install bundler` 29 | 7. `gem install rails --no-ri --no-rdoc` 30 | 8. `git add .` 31 | 9. `git commit -m "Created gemset."` 32 | 10. `rails new . -T` 33 | 11. `git add .` 34 | 12. `git commit -m "fresh Rails install"` 35 | 13. open and edit `Gemfile` with [gems](#gems), save! 36 | 14. `bundle install --without production` 37 | 38 | ## Gems 39 | - **better errors** (in `group :development`): 40 | ```ruby 41 | # Better Errors for debugging 42 | gem 'better_errors' 43 | gem 'binding_of_caller' 44 | ``` 45 | - **Pry Rails** (in `group :development`): `gem 'pry-rails'` 46 | - **[RSpec](#rspec)** (in test section): `gem 'rspec-rails'` 47 | - `rails generate rspec:install` 48 | - Add `--format doc` to .rspec file to see words 49 | - **Factory Girl** (in `group :test`): `gem 'factory_girl_rails', '~> 4.0'` 50 | - Add to config block in spec_helper.rb `config.include FactoryGirl::Syntax::Methods` and `require 'factory_girl'` to top of file 51 | - Create file to define factories: `touch spec/factories.rb` 52 | - **SimpleCov** (in `group :test`): `gem 'simplecov', require: false` 53 | - add to spec/spec_helper.rb 54 | ```ruby 55 | require 'simplecov' 56 | SimpleCov.start 'rails' 57 | ``` 58 | - add `coverage` to .gitignore 59 | - **Bootstrap**: `gem 'bootstrap-sass'` 60 | - create custom.css.scss file for your own custom CSS 61 | - add to _custom.css.scss_ 62 | ```css 63 | @import "bootstrap-sprockets"; 64 | @import "bootstrap"; 65 | ``` 66 | - add to _app/assets/javascripts/application.js_ 67 | ``` 68 | //= require jquery 69 | //= require bootstrap-sprockets 70 | ``` 71 | - restart rails server if already open 72 | - **[bcrypt](#user-authentication)** (click link for more info): `gem 'bcrypt'` 73 | - add `has_secure_password` to User model associations 74 | - **CarrierWave**: add `gem 'mini_magick'` BEFORE `gem 'carrierwave'` 75 | - If imagemagick is not installed: `brew install imagemagick` 76 | - `rails g uploader image`, image can be called anything: avatar, cover_art, etc. 77 | - `rails g migration adds_image_to_albums`, to add a reference column (for the image) to database 78 | - Add `add_column :albums, :image, :string` to new migration file. 79 | - `rake db:migrate` 80 | - Open Album Model and add `# Mounted Objects -----------------------` 81 | - Add `mount_uploader :image, ImageUploader` under "Mounted Objects" 82 | - Go to uploaders/image_uploader.rb, uncomment line 7 `include CarrierWave::MiniMagick` 83 | - line 35 block allows you to resize image as it's uploaded, uncomment to resize images to thumbnails (50px by 50px) 84 | - add another block to create another version of image transformation (if desired) 85 | - uncomment file extensions on line 41 to allow only certain file ext. (jpg, png, gif) 86 | - Add `:image` to albums_params in AlbumsController 87 | - Able to use these methods `.image_url` and `.image_url(:thumb)` 88 | - Add `public/uploads/` to .gitignore 89 | - **HTTParty**: `gem 'httparty'` 90 | - `require 'HTTParty'` wherever you're using it 91 | - Example: 92 | - `weather_url = "http://api.openweathermap.org/data/2.5/weather?q=Seattle&units=imperial"` 93 | - `r = HTTParty.get(weather_url)` 94 | - **OmniAuth** 95 | - Note different providers have their own gems they maintain and one can use: 96 | ```ruby 97 | # OmniAuth Gems 98 | gem 'omniauth' 99 | gem 'omniauth-github' 100 | ``` 101 | - Go to GitHub to register new application (in profile settings --> applications --> Developer Applications -- Register New Application) 102 | - Authorization callback URL: `http://localhost:3000/auth/github/callback` 103 | - Follow remaining steps here: [OmniAuth](https://github.com/Ada-Developers-Academy/daily-curriculum/blob/master/topic_resources/omniauth.md) 104 | - **VCR** (in `group :test`): `gem 'vcr'` 105 | - [VCR github](https://github.com/vcr/vcr) 106 | - Used to test API calls in RSpec 107 | - if deploying to **heroku**: move sqlite3 gem to development, then add 108 | ```ruby 109 | group :production do 110 | gem 'pg' 111 | end 112 | ``` 113 | 114 | ## Show All Routes 115 | `rake routes` 116 | 117 | 118 | ## Make a Model 119 | `rails generate model modelname columnname1:type columnname2:type columname3:type` 120 | - Example: `rails generate model student name:string cohort:string birthday:datetime` 121 | 122 | 123 | ## Make a Controller 124 | `rails generate controller controller_name` 125 | - Example: `rails generate controller tasks` 126 | - convention says controller name is plural 127 | - i.e. ClientsController preferred over ClientController 128 | 129 | 130 | ## Add Column 131 | `rails generate migration add_columnname_to_tablename column:type` 132 | - Example: `rails generate migration add_personid_to_tasks personid:integer` 133 | 134 | 135 | ## Remove Column 136 | `rails generate migration remove_columnname_from_tablename column:type` 137 | - Example: `rails generate migration remove_personalid_from_tasks personid:integer` 138 | 139 | 140 | ## Resource Routing 141 | #### _All routes_ 142 | `resources :labels` 143 | 144 | #### _Only certain routes_ 145 | ` resources :labels, only: [:index, :show]` 146 | 147 | #### _All routes EXCEPT_ 148 | ` resources :labels, except: [:index, :show]` 149 | 150 | #### _Taking a Block_ 151 | ```ruby 152 | resources :labels do 153 | # 8 more routes generated 154 | resources :albums 155 | end 156 | ``` 157 | 158 | #### _Nesting Routes_ 159 | Shouldn't nest more than one deep 160 | 161 | ```ruby 162 | resources :labels do 163 | resources :albums 164 | resources :artists do 165 | resources :albums, only: [:index, :show] 166 | end 167 | end 168 | ``` 169 | 170 | #### _Collection Routes_ 171 | ```ruby 172 | resources :albums, only: [:index, :show] do 173 | collection do 174 | get 'released/:year', action: 'by_year', as: 'by_year' 175 | end 176 | end 177 | ``` 178 | - `get 'released/:year' => 'albums#by_year'` 179 | - `as: 'bye_year'` allows for `by_year_albums_path` for linking 180 | - also have `by_year_albums_url` for linking offsite 181 | 182 | 183 | ## RSpec 184 | 1. Add gem to development section `gem 'rspec-rails', '~> 3.0'` 185 | 2. `bundle` 186 | 3. `rails generate rspec:install` 187 | 4. Add `--format doc` to .rspec file to see words 188 | 189 | #### _Model Specs_ (example) 190 | 1. To generate tests for Album model `rails generate rspec:model Album` 191 | 2. Go to spec -> model -> album_spec to edit specs 192 | 3. Edit specs 193 | 4. To run, use `rspec` command in terminal 194 | 195 | #### _For Controller_ (example) 196 | 1. To generate tests for Albums controller`rails generate rspec:controller albums` 197 | 2. Go to spec -> controllers -> album_controller_spec to edit specs 198 | 3. Edit specs 199 | 4. To run, use `rspec` command in terminal 200 | 201 | To run a spec for a specific folder 202 | `rspec folder/path` 203 | For example, `rspec spec/controllers` 204 | 205 | 206 | ## Heroku Deployment 207 | _Make sure your sqlite3 gem is under development group and add gem 'pg' is in production group_ 208 | 209 | 1. Make sure current project is committed, `git commit -m "Your message here"` 210 | 2. `heroku create NAMEOFSITE` 211 | - ex: `heroku create myapp` will create myapp.herokuapp.com 212 | 3. `git push heroku branch:master` 213 | 4. `heroku run rake db:migrate` 214 | 5. `heroku run rake db:seed` 215 | 216 | #### _If db:drop doesn't work_ 217 | 1. `heroku pg:reset DATABASE` 218 | 2. `heroku run rake db:migrate` 219 | 3. `heroku run rake db:seed` 220 | 4. `heroku restart` 221 | 222 | 223 | ## User Authentication 224 | 1. add `gem 'bcrypt'` 225 | 2. `bundle` 226 | 3. `rails g model User name:string email:string password_digest:string` 227 | 4. Add `has_secure_password` to User model (-> app/model/user.rb) 228 | - Methods available for models w/ 'password_digest defined': `user.password` and `user.password_confirmation` 229 | - will not save password if these two values don't match 230 | - `user.authenticate` allows one to check if password matches existing stored `password_digest` 231 | - `User.find_by(name: 'david').try(:authenticate, 'newd00les')` 232 | 5. Add `home_controller.rb` and `root 'home#index'` to show a home page 233 | 6. `rails g controller sessions` 234 | 7. Add `new`, `create`, and `destroy` methods to SessionsController. 235 | 236 | #### _Routes_ 237 | ```ruby 238 | root 'home#index' 239 | resources :users 240 | resources :sessions, :only => [:new, :create, :destroy] 241 | ``` 242 | 243 | ## Callbacks 244 | _Callbacks allow you to trigger logic before or after an alteration of an object's state._ 245 | - Example: `before_validation :ensure_login_has_a_value` 246 | - Example: `after_validation :set_location, on: [ :create, :update ]` 247 | 248 | 249 | ## Filters 250 | _Filters are methods that are run before, after or "around" a controller action._ 251 | 252 | - Example: `before_action :require_login` 253 | - Example: `skip_before_action :require_login, only: [:new, :create]` 254 | - Example: `around_action :wrap_in_transaction, only: :show` 255 | 256 | 257 | ## FactoryGirl 258 | - Defining a factory within Book model: 259 | ```ruby 260 | FactoryGirl.define do 261 | factory :book do 262 | name "House of Leaves" 263 | author "Mark Z. Danielewski" 264 | description "House of Leaves is the debut novel by the American author Mark Z. Danielewski, published by Pantheon Books. The novel quickly became a bestseller following its release on March 7, 2000. It was followed by a companion piece, The Whalestoe Letters" 265 | end 266 | end 267 | ``` 268 | - Using in testing: 269 | ```ruby 270 | describe Book do 271 | 272 | describe "validations" do 273 | it "is valid" do 274 | expect(create(:book)).to be_valid 275 | end 276 | 277 | it "is invalid without a name" do 278 | expect(build(:book, name: nil)).to be_invalid 279 | end 280 | 281 | end 282 | end 283 | ``` 284 | 285 | - old way: 286 | - `@book = Book.create(name: "", author: "", description: "")` 287 | - factory way: 288 | - `@book = create(:book)` 289 | - `10.times { create(:book) }` 290 | - `@unsaved_book = build(:book)` 291 | --------------------------------------------------------------------------------