Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to Ruby on Rails

Damir
March 13, 2014

Introduction to Ruby on Rails

A head-first dive into the awesomeness of Ruby on Rails, with theoretical background on HTTP, REST and MVC

Damir

March 13, 2014
Tweet

More Decks by Damir

Other Decks in Programming

Transcript

  1. What does it do? create create README.rdoc create Rakefile create

    config.ru create .gitignore create Gemfile create app create app/assets/javascripts/application.js create app/assets/stylesheets/application.css create app/controllers/application_controller.rb create app/helpers/application_helper.rb create app/views/layouts/application.html.erb create app/assets/images/.keep create app/mailers/.keep create app/models/.keep create app/controllers/concerns/.keep create app/models/concerns/.keep create bin create bin/bundle create bin/rails create bin/rake create config create config/routes.rb create config/application.rb create config/environment.rb create config/environments create config/environments/… create config/initializers create config/initializers/… create config/locales create config/locales/en.yml create config/boot.rb create config/database.yml create db create db/seeds.rb create lib create lib/tasks create lib/tasks/.keep create lib/assets create lib/assets/.keep create log create log/.keep create public create public/404.html create public/422.html create public/500.html create public/favicon.ico create public/robots.txt create test/fixtures create test/fixtures/.keep create test/controllers create test/controllers/.keep create test/mailers create test/mailers/.keep create test/models create test/models/.keep create test/helpers create test/helpers/.keep create test/integration create test/integration/.keep create test/test_helper.rb create tmp/cache create tmp/cache/assets create vendor/assets/javascripts create vendor/assets/javascripts/.keep create vendor/assets/stylesheets create vendor/assets/stylesheets/.keep run bundle install Creates A LOT OF files
  2. HTTP Status Codes 200 OK 404 Page Not Found 403

    Forbidden 422 Unprocessable Entity 500 Internal Server Error
  3. REST Architectural style Resources identifiable in request Representation sufficient to

    allow resource modification State transitions connect resources
  4. hash = { id: 1, name: "John" } hash[:id] #

    => 1 hash[:name] # => "John"
  5. What does it do? create create README.rdoc create Rakefile create

    config.ru create .gitignore create Gemfile create app create app/assets/javascripts/application.js create app/assets/stylesheets/application.css create app/controllers/application_controller.rb create app/helpers/application_helper.rb create app/views/layouts/application.html.erb create app/assets/images/.keep create app/mailers/.keep create app/models/.keep create app/controllers/concerns/.keep create app/models/concerns/.keep create bin create bin/bundle create bin/rails create bin/rake create config create config/routes.rb create config/application.rb create config/environment.rb create config/environments create config/environments/… create config/initializers create config/initializers/… create config/locales create config/locales/en.yml create config/boot.rb create config/database.yml create db create db/seeds.rb create lib create lib/tasks create lib/tasks/.keep create lib/assets create lib/assets/.keep create log create log/.keep create public create public/404.html create public/422.html create public/500.html create public/favicon.ico create public/robots.txt create test/fixtures create test/fixtures/.keep create test/controllers create test/controllers/.keep create test/mailers create test/mailers/.keep create test/models create test/models/.keep create test/helpers create test/helpers/.keep create test/integration create test/integration/.keep create test/test_helper.rb create tmp/cache create tmp/cache/assets create vendor/assets/javascripts create vendor/assets/javascripts/.keep create vendor/assets/stylesheets create vendor/assets/stylesheets/.keep run bundle install
  6. What does it do? create create README.rdoc create Rakefile create

    config.ru create .gitignore create Gemfile create app create app/assets/javascripts/application.js create app/assets/stylesheets/application.css create app/controllers/application_controller.rb create app/helpers/application_helper.rb create app/views/layouts/application.html.erb create app/assets/images/.keep create app/mailers/.keep create app/models/.keep create app/controllers/concerns/.keep create app/models/concerns/.keep create bin create bin/bundle create bin/rails create bin/rake create config create config/routes.rb create config/application.rb create config/environment.rb create config/environments create config/environments/… create config/initializers create config/initializers/… create config/locales create config/locales/en.yml create config/boot.rb create config/database.yml create db create db/seeds.rb create lib create lib/tasks create lib/tasks/.keep create lib/assets create lib/assets/.keep create log create log/.keep create public create public/404.html create public/422.html create public/500.html create public/favicon.ico create public/robots.txt create test/fixtures create test/fixtures/.keep create test/controllers create test/controllers/.keep create test/mailers create test/mailers/.keep create test/models create test/models/.keep create test/helpers create test/helpers/.keep create test/integration create test/integration/.keep create test/test_helper.rb create tmp/cache create tmp/cache/assets create vendor/assets/javascripts create vendor/assets/javascripts/.keep create vendor/assets/stylesheets create vendor/assets/stylesheets/.keep
  7. Let's look at the new files app/assets/javascripts/rooms.js.coffee app/assets/stylesheets/rooms.css.scss app/controllers/rooms_controller.rb app/helpers/rooms_helper.rb

    app/models/room.rb app/views/rooms/_form.html.erb app/views/rooms/edit.html.erb app/views/rooms/index.html.erb app/views/rooms/index.json.jbuilder app/views/rooms/new.html.erb app/views/rooms/show.html.erb app/views/rooms/show.json.jbuilder config/routes.rb db/migrate/20140311195644_create_rooms.rb db/schema.rb test/controllers/rooms_controller_test.rb test/fixtures/rooms.yml test/helpers/rooms_helper_test.rb test/models/room_test.rb
  8. Model app/assets/javascripts/rooms.js.coffee app/assets/stylesheets/rooms.css.scss app/controllers/rooms_controller.rb app/helpers/rooms_helper.rb app/models/room.rb app/views/rooms/_form.html.erb app/views/rooms/edit.html.erb app/views/rooms/index.html.erb app/views/rooms/index.json.jbuilder

    app/views/rooms/new.html.erb app/views/rooms/show.html.erb app/views/rooms/show.json.jbuilder config/routes.rb db/migrate/20140311195644_create_rooms.rb db/schema.rb test/controllers/rooms_controller_test.rb test/fixtures/rooms.yml test/helpers/rooms_helper_test.rb test/models/room_test.rb
  9. Views app/assets/javascripts/rooms.js.coffee app/assets/stylesheets/rooms.css.scss app/controllers/rooms_controller.rb app/helpers/rooms_helper.rb app/models/room.rb app/views/rooms/_form.html.erb app/views/rooms/edit.html.erb app/views/rooms/index.html.erb app/views/rooms/index.json.jbuilder

    app/views/rooms/new.html.erb app/views/rooms/show.html.erb app/views/rooms/show.json.jbuilder config/routes.rb db/migrate/20140311195644_create_rooms.rb db/schema.rb test/controllers/rooms_controller_test.rb test/fixtures/rooms.yml test/helpers/rooms_helper_test.rb test/models/room_test.rb
  10. <p> <strong>Name:</strong> <%= @room.name %> </p> ! <p> <strong>Description:</strong> <%=

    @room.description %> </p> ! <%= link_to 'Edit', edit_room_path(@room) %> | <%= link_to 'Back', rooms_path %>
  11. <p> <strong>Name:</strong> <%= @room.name %> </p> ! <p> <strong>Description:</strong> <%=

    @room.description %> </p> ! <%= link_to 'Edit', edit_room_path(@room) %> | <%= link_to 'Back', rooms_path %> Render model! attributes
  12. <p> <strong>Name:</strong> <%= @room.name %> </p> ! <p> <strong>Description:</strong> <%=

    @room.description %> </p> ! <%= link_to 'Edit', edit_room_path(@room) %> | <%= link_to 'Back', rooms_path %> Render links
  13. Controller app/assets/javascripts/rooms.js.coffee app/assets/stylesheets/rooms.css.scss app/controllers/rooms_controller.rb app/helpers/rooms_helper.rb app/models/room.rb app/views/rooms/_form.html.erb app/views/rooms/edit.html.erb app/views/rooms/index.html.erb app/views/rooms/index.json.jbuilder

    app/views/rooms/new.html.erb app/views/rooms/show.html.erb app/views/rooms/show.json.jbuilder config/routes.rb db/migrate/20140311195644_create_rooms.rb db/schema.rb test/controllers/rooms_controller_test.rb test/fixtures/rooms.yml test/helpers/rooms_helper_test.rb test/models/room_test.rb
  14. class RoomsController < ApplicationController before_action :set_room, only: [:show, :edit, :update,

    :destroy] ! def index @rooms = Room.all end ! def show end ! def new @room = Room.new end ! private ! def set_room @room = Room.find(params[:id]) end end
  15. class RoomsController < ApplicationController before_action :set_room, only: [:show, :edit, :update,

    :destroy] ! def index @rooms = Room.all end ! def show end ! def new @room = Room.new end ! private ! def set_room @room = Room.find(params[:id]) end end Class name Base class name
  16. class RoomsController < ApplicationController before_action :set_room, only: [:show, :edit, :update,

    :destroy] ! def index @rooms = Room.all end ! def show end ! def new @room = Room.new end ! private ! def set_room @room = Room.find(params[:id]) end end Controller name Base controller Controllers are classes
  17. class RoomsController < ApplicationController before_action :set_room, only: [:show, :edit, :update,

    :destroy] ! def index @rooms = Room.all end ! def show end ! def new @room = Room.new end ! private ! def set_room @room = Room.find(params[:id]) end end Instance method Instance variable
  18. class RoomsController < ApplicationController before_action :set_room, only: [:show, :edit, :update,

    :destroy] ! def index @rooms = Room.all end ! def show end ! def new @room = Room.new end ! private ! def set_room @room = Room.find(params[:id]) end end Action Controller actions are methods
  19. class RoomsController < ApplicationController before_action :set_room, only: [:show, :edit, :update,

    :destroy] ! def index @rooms = Room.all end ! def show end ! def new @room = Room.new end ! private ! def set_room @room = Room.find(params[:id]) end end Retrieves all rooms from DB
  20. class RoomsController < ApplicationController before_action :set_room, only: [:show, :edit, :update,

    :destroy] ! def index @rooms = Room.all end ! def show end ! def new @room = Room.new end ! private ! def set_room @room = Room.find(params[:id]) end end "Macro"! (a class method) Private methods
  21. class RoomsController < ApplicationController before_action :set_room, only: [:show, :edit, :update,

    :destroy] ! def index @rooms = Room.all end ! def show end ! def new @room = Room.new end ! private ! def set_room @room = Room.find(params[:id]) end end Macros are used to! create callbacks Private methods! are not actions
  22. class RoomsController < ApplicationController before_action :set_room, only: [:show, :edit, :update,

    :destroy] ! def index @rooms = Room.all end ! def show end ! def new @room = Room.new end ! private ! def set_room @room = Room.find(params[:id]) end end Macros are used to! create callbacks Finds a single room by ID
  23. class RoomsController < ApplicationController before_action :set_room, only: [:show, :edit, :update,

    :destroy] ! def index @rooms = Room.all end ! def show end ! def new @room = Room.new end ! private ! def set_room @room = Room.find(params[:id]) end end Macros are used to! create callbacks "params" is a hash with! data submitted by a user
  24. def create @room = Room.new(room_params) ! respond_to do |format| if

    @room.save format.html { redirect_to @room, notice: 'Room was successfully created.' } format.json { render action: 'show', status: :created, location: @room } else format.html { render action: 'new' } format.json { render json: @room.errors, status: :unprocessable_entity } end end end Create new room from what???
  25. class RoomsController < ApplicationController before_action :set_room, only: [:show, :edit, :update,

    :destroy] ! # … ! def create # … end ! # … ! private ! # … ! # Never trust parameters from the scary internet, # only allow the white list through. def room_params params.require(:room).permit(:name, :description) end end
  26. def create @room = Room.new(room_params) ! respond_to do |format| if

    @room.save format.html { redirect_to @room, notice: 'Room was successfully created.' } format.json { render action: 'show', status: :created, location: @room } else format.html { render action: 'new' } format.json { render json: @room.errors, status: :unprocessable_entity } end end end Good, we're safe
  27. def create @room = Room.new(room_params) ! respond_to do |format| if

    @room.save format.html { redirect_to @room, notice: 'Room was successfully created.' } format.json { render action: 'show', status: :created, location: @room } else format.html { render action: 'new' } format.json { render json: @room.errors, status: :unprocessable_entity } end end end
  28. def create @room = Room.new(room_params) ! respond_to do |format| if

    @room.save format.html { redirect_to @room, notice: 'Room was successfully created.' } format.json { render action: 'show', status: :created, location: @room } else format.html { render action: 'new' } format.json { render json: @room.errors, status: :unprocessable_entity } end end end HTML representation JSON representation! (API) Pick a format
  29. Router app/assets/javascripts/rooms.js.coffee app/assets/stylesheets/rooms.css.scss app/controllers/rooms_controller.rb app/helpers/rooms_helper.rb app/models/room.rb app/views/rooms/_form.html.erb app/views/rooms/edit.html.erb app/views/rooms/index.html.erb app/views/rooms/index.json.jbuilder

    app/views/rooms/new.html.erb app/views/rooms/show.html.erb app/views/rooms/show.json.jbuilder config/routes.rb db/migrate/20140311195644_create_rooms.rb db/schema.rb test/controllers/rooms_controller_test.rb test/fixtures/rooms.yml test/helpers/rooms_helper_test.rb test/models/room_test.rb
  30. Database migration app/assets/javascripts/rooms.js.coffee app/assets/stylesheets/rooms.css.scss app/controllers/rooms_controller.rb app/helpers/rooms_helper.rb app/models/room.rb app/views/rooms/_form.html.erb app/views/rooms/edit.html.erb app/views/rooms/index.html.erb

    app/views/rooms/index.json.jbuilder app/views/rooms/new.html.erb app/views/rooms/show.html.erb app/views/rooms/show.json.jbuilder config/routes.rb db/migrate/20140311195644_create_rooms.rb db/schema.rb test/controllers/rooms_controller_test.rb test/fixtures/rooms.yml test/helpers/rooms_helper_test.rb test/models/room_test.rb
  31. # db/migrate/201403xxxxxxxx_create_rooms.rb ! class CreateRooms < ActiveRecord::Migration def change create_table

    :rooms do |t| t.string :name t.text :description ! t.timestamps end end end
  32. # db/schema.rb ! ActiveRecord::Schema.define(version: 20140311195644) do ! create_table "rooms", force:

    true do |t| t.string "name" t.text "description" t.datetime "created_at" t.datetime "updated_at" end ! end
  33. Associations A reservation belongs to a team A reservation belongs

    to a room A room has many reservations A team has many reservations
  34. Associations db/migrate/201403xxxxxxxx_create_reservations.rb ! create_table "reservations" do |t| t.integer "room_id" t.integer

    "team_id" t.datetime "from" t.datetime "until" t.datetime "created_at" t.datetime "updated_at" end
  35. Select lists <div class="field"> <%= f.label :room %><br> <%= f.text_field

    :room %> </div> <div class="field"> <%= f.label :team %><br> <%= f.text_field :team %> </div> <div class="field"> <%= f.label :from %><br> <%= f.datetime_select :from %> </div> <div class="field"> <%= f.label :until %><br> <%= f.datetime_select :until %> </div>
  36. Select lists <div class="field"> <%= f.label :room %><br> <%= f.text_field

    :room %> </div> <div class="field"> <%= f.label :team %><br> <%= f.text_field :team %> </div> <div class="field"> <%= f.label :from %><br> <%= f.datetime_select :from %> </div> <div class="field"> <%= f.label :until %><br> <%= f.datetime_select :until %> </div>
  37. Select lists <div class="field"> <%= f.label :room %><br> <%= f.collection_select

    :room_id, Room.all, :id, :name %> </div> <div class="field"> <%= f.label :team %><br> <%= f.collection_select :team_id, Team.all, :id, :name %> </div> <div class="field"> <%= f.label :from %><br> <%= f.datetime_select :from %> </div> <div class="field"> <%= f.label :until %><br> <%= f.datetime_select :until %> </div>
  38. Relation display # app/views/reservations/show.html.erb ! <p> <strong>Room:</strong> <%= @reservation.room %>

    </p> ! <p> <strong>Team:</strong> <%= @reservation.team %> </p> ! <p> <strong>From:</strong> <%= @reservation.from %> </p> ! <p> <strong>Until:</strong> <%= @reservation.until %> </p>
  39. Relation display # app/views/reservations/show.html.erb ! <p> <strong>Room:</strong> <%= @reservation.room %>

    </p> ! <p> <strong>Team:</strong> <%= @reservation.team %> </p> ! <p> <strong>From:</strong> <%= @reservation.from %> </p> ! <p> <strong>Until:</strong> <%= @reservation.until %> </p>
  40. Relation display # app/views/reservations/show.html.erb ! <p> <strong>Room:</strong> <%= @reservation.room.name %>

    </p> ! <p> <strong>Team:</strong> <%= @reservation.team.name %> </p> ! <p> <strong>From:</strong> <%= @reservation.from %> </p> ! <p> <strong>Until:</strong> <%= @reservation.until %> </p>
  41. Date/time format # app/views/reservations/show.html.erb ! <p> <strong>Room:</strong> <%= @reservation.room.name %>

    </p> ! <p> <strong>Team:</strong> <%= @reservation.team.name %> </p> ! <p> <strong>From:</strong> <%= @reservation.from %> </p> ! <p> <strong>Until:</strong> <%= @reservation.until %> </p>
  42. Date/time format # app/views/reservations/show.html.erb ! <p> <strong>Room:</strong> <%= @reservation.room.name %>

    </p> ! <p> <strong>Team:</strong> <%= @reservation.team.name %> </p> ! <p> <strong>From:</strong> <%= @reservation.from.to_s(:short) %> </p> ! <p> <strong>Until:</strong> <%= @reservation.until.to_s(:short) %> </p>
  43. Photo upload Where to store images?! Server's hard drive Database

    Cloud Problematic with! deployments Just… don't
  44. Gems # Gemfile ! source 'https://rubygems.org' ! gem 'rails', '4.0.0'

    gem 'sqlite3' gem 'sass-rails', '~> 4.0.0' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.0.0' gem 'jquery-rails' gem 'turbolinks' gem 'jbuilder', '~> 1.2' ! group :doc do gem 'sdoc', require: false end
  45. Gems # Gemfile ! source 'https://rubygems.org' ! gem 'rails', '4.0.0'

    gem 'sqlite3' gem 'sass-rails', '~> 4.0.0' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.0.0' gem 'jquery-rails' gem 'turbolinks' gem 'jbuilder', '~> 1.2' ! gem 'carrierwave' gem 'cloudinary' ! group :doc do gem 'sdoc', require: false end
  46. Edit the last migration # db/migrate/201403xxxxxxxx_add_photo_to_room.rb ! class AddPhotoToRoom <

    ActiveRecord::Migration def change add_column :rooms, :photo, :string end end
  47. And setup the model # app/models/room.rb ! class Room <

    ActiveRecord::Base mount_uploader :photo, RoomPhotoUploader end
  48. Modify the form… # app/views/rooms/_form.html.erb ! <div class="field"> <%= f.label

    :name %><br> <%= f.text_field :name %> </div> <div class="field"> <%= f.label :description %><br> <%= f.text_area :description %> </div> <div class="field"> <%= f.hidden_field(:photo_cache) %> <%= f.label :photo %><br> <%= f.file_field(:photo) %> </div>
  49. Display the photo… # app/views/rooms/show.html.erb ! <p> <strong>Name:</strong> <%= @room.name

    %> </p> ! <p> <strong>Description:</strong> <%= @room.description %> </p> ! <% if @room.photo %> <p> <%= link_to @room.photo.url do %> <%= cl_image_tag(@room.photo, width: 200, height: 200, crop: :fit) %> <% end %> </p> <% end %>
  50. WARNING "If you are building your first Rails application, we

    recommend you to not use Devise. Devise requires a good understanding of the Rails Framework. In such cases, we advise you to start a simple authentication system from scratch."
  51. Gems # Gemfile ! source 'https://rubygems.org' ! gem 'rails', '4.0.0'

    gem 'sqlite3' gem 'sass-rails', '~> 4.0.0' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.0.0' gem 'jquery-rails' gem 'turbolinks' gem 'jbuilder', '~> 1.2' ! gem 'carrierwave' gem 'cloudinary' gem 'devise' ! group :doc do gem 'sdoc', require: false end
  52. Customize signup template # app/views/devise/registrations/new.html.erb ! <h2>Sign up</h2> ! <%=

    form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> <%= devise_error_messages! %> ! <div><%= f.label :email %><br /> <%= f.email_field :email, autofocus: true %></div> ! <div><%= f.label :password %><br /> <%= f.password_field :password %></div> ! <div><%= f.label :password_confirmation %><br /> <%= f.password_field :password_confirmation %></div> ! <div><%= f.submit "Sign up" %></div> <% end %> ! <%= render "devise/shared/links" %>
  53. Customize signup template # app/views/devise/registrations/new.html.erb ! <h2>Sign up</h2> ! <%=

    form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> <%= devise_error_messages! %> ! <div><%= f.label :name %><br /> <%= f.text_field :name, autofocus: true %></div> ! <div><%= f.label :email %><br /> <%= f.email_field :email %></div> ! <div><%= f.label :password %><br /> <%= f.password_field :password %></div> ! <div><%= f.label :password_confirmation %><br /> <%= f.password_field :password_confirmation %></div> ! <div><%= f.submit "Sign up" %></div> <% end %> ! <%= render "devise/shared/links" %>
  54. Whitelist the attribute # app/controllers/application_controller.rb ! class ApplicationController < ActionController::Base

    protect_from_forgery with: :exception before_action :authenticate_team! before_action :configure_permitted_parameters, if: :devise_controller? ! private ! def configure_permitted_parameters devise_parameter_sanitizer.for(:sign_up) << :name end end
  55. Next steps Prevent other teams to:! edit team info delete

    teams create new teams change reservations
  56. Gems # Gemfile ! source 'https://rubygems.org' ! gem 'rails', '4.0.0'

    gem 'sqlite3' gem 'sass-rails', '~> 4.0.0' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.0.0' gem 'jquery-rails' gem 'turbolinks' gem 'jbuilder', '~> 1.2' ! gem 'carrierwave' gem 'cloudinary' gem 'devise' gem 'bootstrap-sass', '~> 3.1.1' ! group :doc do gem 'sdoc', require: false end
  57. Change CSS # app/assets/stylesheets/application.css ! /* * This is a

    manifest file that'll be compiled into application.css, which will include all the files * listed below. * * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. * * You're free to add application-wide styles to this file and they'll appear at the top of the * compiled file, but it's generally better to create a new file per style scope. * *= require_self *= require_tree . */
  58. Prettify the app! # app/views/reservations/index.html.erb ! <%= link_to 'Show', reservation

    %> <% if reservation.team == current_team %> <%= link_to 'Edit', edit_reservation_path(reservation) %> <%= link_to 'Destroy', reservation, method: :delete, data: { confirm: 'Are you sure?' } %> <% end %>
  59. Prettify the app! # app/views/reservations/index.html.erb ! <div class="btn-group"> <%= link_to

    'Show', reservation, class: "btn btn-primary" %> <% if reservation.team == current_team %> <%= link_to 'Edit', edit_reservation_path(reservation), class: "btn btn-default" %> <%= link_to 'Destroy', reservation, method: :delete, class: "btn btn-danger", data: { confirm: 'Are you sure?' } %> <% end %> </div>
  60. Add navbar # app/views/layouts/application.html.erb ! <nav class="navbar navbar-default" role="navigation"> <div

    class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/">Room Reservations</a> </div> ! <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li> <%= link_to "Reservations", reservations_path %> </li> <li> <%= link_to "Rooms", rooms_path %> </li> <li> <%= link_to "Teams", teams_path %> </li> </ul> ! <% if team_signed_in? %> <ul class="nav navbar-nav navbar-right"> <li> <p class="navbar-text"> <%= current_team.name %> </p> </li> <li> <%= form_tag destroy_team_session_path, method: :delete, class: 'navbar-form navbar-right' do %> <%= button_tag "Sign out", class: 'btn btn-default' %> <% end %> </li> </ul> <% end %> </div>
  61. Also modify JS # app/assets/javascripts/application.js ! //= require jquery //=

    require jquery_ujs //= require turbolinks //= require bootstrap //= require_tree .
  62. Code for Room Reservation:
 https://github.com/sidonath/room-reservations/ Guides to various Rails-related topics:


    http://guides.rubyonrails.org/ CarrierWave homepage:
 https://github.com/carrierwaveuploader/carrierwave Cloudinary Rails/CarrierWave docs:
 http://cloudinary.com/documentation/rails_carrierwave Devise Readme:
 https://github.com/plataformatec/devise/tree/v3.2.3 Twitter Bootstrap homepage:
 http://getbootstrap.com/
  63. When you have more time to study Rails or Ruby

    http://tutorials.jumpstartlab.com/ http://mislav.uniqpath.com/poignant-guide/ http://pragprog.com/book/rails4/agile-web-development-with-rails-4