Creating A New App With Chat
NOTE:
Be sure your rails version is greater than or equal to 5.0.0 by running rails -v
We'll start off by generating a new rails app and creating the database:
rails new test-app
rails db:create
Now we'll setup Devise and our User model by adding Devise to the Gemfile and running bundler:
gem 'devise'
Then run the Devise installer:
$ rails generate devise:install
And then generate the User model using devise and migrate:
$ rails generate devise User
$ rails db:migrate
While we are making the User model let's add some extra columns to users table:
$ rails generate migration add_first_name_and_last_name_to_users first_name last_name
Let's also give users the ability to upload an avatar using Paperclip:
# Gemfile
gem 'paperclip'
$ bundle
$ rails generate paperclip user avatar
$ rails db:migrate
# app/models/user.rb
class User < ApplicationRecord
has_attached_file :avatar
validates_attachment :avatar, content_type: {
content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif"]
}
...
end
Since we are adding extra fields to the User model we will need to update the signup form and RegistrationsController:
<!-- app/views/devise/registrations.html.erb -->
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :first_name %><br />
<%= f.text_field :first_name %>
</div>
<div class="field">
<%= f.label :last_name %><br />
<%= f.text_field :last_name %>
</div>
<div class="field">
<%= f.label :avatar %><br />
<%= f.file_field :avatar %>
</div>
<div class="field">
<%= f.label :password %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
# app/views/controller/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
private
def sign_up_params
params.require(:user).permit(:first_name, :last_name, :avatar, :email, :password, :password_confirmation)
end
def account_update_params
params.require(:user).permit(:first_name, :last_name, :avatar, :email, :password, :password_confirmation, :current_password)
end
end
And finally update the devise route to use this new controller:
# config/routes
devise_for :users, :controllers => { registrations: 'registrations' }
We'll then use HighVoltage to setup a static page by adding it to the Gemfile and running bundler:
gem 'high_voltage'
Now that HighVoltage is installed, let's create a static page:
<!-- app/views/pages/home.html.erb -->
<div id="homeContainer">
<% if user_signed_in? %>
<%= link_to "Logout", destroy_user_session_path, method: :delete %>
<h1>Chat</h1>
<% else %>
<%= link_to new_user_session_path do %>
<h1>Chat</h1>
<% end %>
<% end %>
</div>
And let's add it as our root route:
root to: 'high_voltage/pages#show', id: 'home'
Now let's finish setting up ActionCable by uncommenting out the redis gem in your Gemfile and running bundler:
gem 'redis', '~> 3.0'
Mount ActionCable's route in the routes file:
mount ActionCable.server => '/cable'
Add the ActionCable meta tag to the head of your application.html.erb
<%= action_cable_meta_tag %>
Finally let's set up our connection so it only works with authenticated users.
# app/channels/application_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
end
protected
def find_verified_user
if (verified_user = User.find_by(id: cookies.signed['user.id']))
verified_user
else
reject_unauthorized_connection
end
end
end
end
Now lets add Chat into the mix. Add it to your Gemfile:
gem 'chat'
And install it:
$ bundle install
$ rails generate chat:install
$ rails db:migrate
And then add the required js and css files:
app/assets/javascripts/application.js
//= require chat
app/assets/stylesheets/application.css
*= require chat
Now lets update the chat initializer with the devise methods:
Chat.setup do |config|
config.signed_in = :user_signed_in?
config.logged_in_check = :authenticate_user!
config.user_avatar = :avatar
end