Skip to content

Commit 78e1ba3

Browse files
committed
Gems, devise, User, and root route setup
1 parent 6849d61 commit 78e1ba3

31 files changed

+807
-6
lines changed

Gemfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,7 @@ group :test do
7070
gem "selenium-webdriver"
7171
gem "webdrivers"
7272
end
73+
74+
# My additions below
75+
gem 'devise'
76+
gem 'acts_as_tenant'

Gemfile.lock

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,12 @@ GEM
6666
i18n (>= 1.6, < 2)
6767
minitest (>= 5.1)
6868
tzinfo (~> 2.0)
69+
acts_as_tenant (0.6.1)
70+
rails (>= 5.2)
71+
request_store (>= 1.0.5)
6972
addressable (2.8.4)
7073
public_suffix (>= 2.0.2, < 6.0)
74+
bcrypt (3.1.18)
7175
bindex (0.8.1)
7276
bootsnap (1.16.0)
7377
msgpack (~> 1.2)
@@ -87,6 +91,12 @@ GEM
8791
debug (1.8.0)
8892
irb (>= 1.5.0)
8993
reline (>= 0.3.1)
94+
devise (4.9.2)
95+
bcrypt (~> 3.0)
96+
orm_adapter (~> 0.1)
97+
railties (>= 4.1.0)
98+
responders
99+
warden (~> 1.2.3)
90100
erubi (1.12.0)
91101
globalid (1.1.0)
92102
activesupport (>= 5.0)
@@ -127,6 +137,7 @@ GEM
127137
nio4r (2.5.9)
128138
nokogiri (1.15.0-arm64-darwin)
129139
racc (~> 1.4)
140+
orm_adapter (0.5.0)
130141
pg (1.5.3)
131142
public_suffix (5.0.1)
132143
puma (5.6.5)
@@ -166,6 +177,11 @@ GEM
166177
regexp_parser (2.8.0)
167178
reline (0.3.3)
168179
io-console (~> 0.5)
180+
request_store (1.5.1)
181+
rack (>= 1.4)
182+
responders (3.1.0)
183+
actionpack (>= 5.2)
184+
railties (>= 5.2)
169185
rexml (3.2.5)
170186
rubyzip (2.3.2)
171187
selenium-webdriver (4.9.1)
@@ -189,6 +205,8 @@ GEM
189205
railties (>= 6.0.0)
190206
tzinfo (2.0.6)
191207
concurrent-ruby (~> 1.0)
208+
warden (1.2.9)
209+
rack (>= 2.0.9)
192210
web-console (4.2.0)
193211
actionview (>= 6.0.0)
194212
activemodel (>= 6.0.0)
@@ -210,9 +228,11 @@ PLATFORMS
210228
arm64-darwin-22
211229

212230
DEPENDENCIES
231+
acts_as_tenant
213232
bootsnap
214233
capybara
215234
debug
235+
devise
216236
importmap-rails
217237
jbuilder
218238
pg (~> 1.1)

README.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,60 @@ bundle exec rake db:drop db:create db:migrate db:seed
3030
#### Commit: 'Initial project setup', [173d0ac](https://github.com/robault/CustomSubdomains/commit/173d0ac9d8fc611ba4670a20a192eee1e90bf8b4)
3131

3232
---
33+
34+
The video assumes an existing rails project with devise already installed. So I did that setup.
35+
36+
I first added the devise and acts_as_tenant gems to the Gemfile and ran:
37+
38+
```bash
39+
bundle # same as 'bundle install
40+
```
41+
42+
Then ran:
43+
44+
```bash
45+
bundle exec rails generate devise:install
46+
bundle exec rails generate devise:views
47+
```
48+
49+
The devise install walks through the steps to add the following to the config/environments/development.rb file:
50+
51+
```ruby
52+
config.action_mailer.default_url_options = { host: 'lvh.me', port: 3000 }
53+
```
54+
55+
I also added the following to the config/environments/development.rb file to use the 'lvh.me' host name, which is a new requirement in recent versions of Rails:
56+
57+
```ruby
58+
config.hosts << 'lvh.me' # allows lvh.me to work in development
59+
config.hosts << /.*\.lvh\.me/ # allows subdomains to work in development
60+
```
61+
62+
I did not change or configure devise in any other way.
63+
64+
I then created a controller to use as the root of the application:
65+
66+
```bash
67+
bundle exec rails generate controller Hello index
68+
```
69+
...and set the root in the routes.rb file:
70+
71+
```ruby
72+
Rails.application.routes.draw do
73+
root "hello#index"
74+
end
75+
```
76+
77+
Part of the devise setup is to create a User model:
78+
79+
```bash
80+
bundle exec rails generate devise User
81+
```
82+
83+
Then ran the db migration:
84+
85+
```bash
86+
bundle exec rake db:migrate
87+
```
88+
89+
I was then able to start the server and see the root page at: http://lvh.me:3000

app/controllers/hello_controller.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class HelloController < ApplicationController
2+
def index
3+
end
4+
end

app/helpers/hello_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
module HelloHelper
2+
end

app/models/user.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class User < ApplicationRecord
2+
# Include default devise modules. Others available are:
3+
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
4+
devise :database_authenticatable, :registerable,
5+
:recoverable, :rememberable, :validatable
6+
end
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<h2>Resend confirmation instructions</h2>
2+
3+
<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
4+
<%= render "devise/shared/error_messages", resource: resource %>
5+
6+
<div class="field">
7+
<%= f.label :email %><br />
8+
<%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
9+
</div>
10+
11+
<div class="actions">
12+
<%= f.submit "Resend confirmation instructions" %>
13+
</div>
14+
<% end %>
15+
16+
<%= render "devise/shared/links" %>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<p>Welcome <%= @email %>!</p>
2+
3+
<p>You can confirm your account email through the link below:</p>
4+
5+
<p><%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<p>Hello <%= @email %>!</p>
2+
3+
<% if @resource.try(:unconfirmed_email?) %>
4+
<p>We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.</p>
5+
<% else %>
6+
<p>We're contacting you to notify you that your email has been changed to <%= @resource.email %>.</p>
7+
<% end %>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<p>Hello <%= @resource.email %>!</p>
2+
3+
<p>We're contacting you to notify you that your password has been changed.</p>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<p>Hello <%= @resource.email %>!</p>
2+
3+
<p>Someone has requested a link to change your password. You can do this through the link below.</p>
4+
5+
<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %></p>
6+
7+
<p>If you didn't request this, please ignore this email.</p>
8+
<p>Your password won't change until you access the link above and create a new one.</p>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<p>Hello <%= @resource.email %>!</p>
2+
3+
<p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>
4+
5+
<p>Click the link below to unlock your account:</p>
6+
7+
<p><%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %></p>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<h2>Change your password</h2>
2+
3+
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
4+
<%= render "devise/shared/error_messages", resource: resource %>
5+
<%= f.hidden_field :reset_password_token %>
6+
7+
<div class="field">
8+
<%= f.label :password, "New password" %><br />
9+
<% if @minimum_password_length %>
10+
<em>(<%= @minimum_password_length %> characters minimum)</em><br />
11+
<% end %>
12+
<%= f.password_field :password, autofocus: true, autocomplete: "new-password" %>
13+
</div>
14+
15+
<div class="field">
16+
<%= f.label :password_confirmation, "Confirm new password" %><br />
17+
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
18+
</div>
19+
20+
<div class="actions">
21+
<%= f.submit "Change my password" %>
22+
</div>
23+
<% end %>
24+
25+
<%= render "devise/shared/links" %>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<h2>Forgot your password?</h2>
2+
3+
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
4+
<%= render "devise/shared/error_messages", resource: resource %>
5+
6+
<div class="field">
7+
<%= f.label :email %><br />
8+
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
9+
</div>
10+
11+
<div class="actions">
12+
<%= f.submit "Send me reset password instructions" %>
13+
</div>
14+
<% end %>
15+
16+
<%= render "devise/shared/links" %>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<h2>Edit <%= resource_name.to_s.humanize %></h2>
2+
3+
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
4+
<%= render "devise/shared/error_messages", resource: resource %>
5+
6+
<div class="field">
7+
<%= f.label :email %><br />
8+
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
9+
</div>
10+
11+
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
12+
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
13+
<% end %>
14+
15+
<div class="field">
16+
<%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
17+
<%= f.password_field :password, autocomplete: "new-password" %>
18+
<% if @minimum_password_length %>
19+
<br />
20+
<em><%= @minimum_password_length %> characters minimum</em>
21+
<% end %>
22+
</div>
23+
24+
<div class="field">
25+
<%= f.label :password_confirmation %><br />
26+
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
27+
</div>
28+
29+
<div class="field">
30+
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
31+
<%= f.password_field :current_password, autocomplete: "current-password" %>
32+
</div>
33+
34+
<div class="actions">
35+
<%= f.submit "Update" %>
36+
</div>
37+
<% end %>
38+
39+
<h3>Cancel my account</h3>
40+
41+
<div>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?", turbo_confirm: "Are you sure?" }, method: :delete %></div>
42+
43+
<%= link_to "Back", :back %>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<h2>Sign up</h2>
2+
3+
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
4+
<%= render "devise/shared/error_messages", resource: resource %>
5+
6+
<div class="field">
7+
<%= f.label :email %><br />
8+
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
9+
</div>
10+
11+
<div class="field">
12+
<%= f.label :password %>
13+
<% if @minimum_password_length %>
14+
<em>(<%= @minimum_password_length %> characters minimum)</em>
15+
<% end %><br />
16+
<%= f.password_field :password, autocomplete: "new-password" %>
17+
</div>
18+
19+
<div class="field">
20+
<%= f.label :password_confirmation %><br />
21+
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
22+
</div>
23+
24+
<div class="actions">
25+
<%= f.submit "Sign up" %>
26+
</div>
27+
<% end %>
28+
29+
<%= render "devise/shared/links" %>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<h2>Log in</h2>
2+
3+
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
4+
<div class="field">
5+
<%= f.label :email %><br />
6+
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
7+
</div>
8+
9+
<div class="field">
10+
<%= f.label :password %><br />
11+
<%= f.password_field :password, autocomplete: "current-password" %>
12+
</div>
13+
14+
<% if devise_mapping.rememberable? %>
15+
<div class="field">
16+
<%= f.check_box :remember_me %>
17+
<%= f.label :remember_me %>
18+
</div>
19+
<% end %>
20+
21+
<div class="actions">
22+
<%= f.submit "Log in" %>
23+
</div>
24+
<% end %>
25+
26+
<%= render "devise/shared/links" %>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<% if resource.errors.any? %>
2+
<div id="error_explanation" data-turbo-cache="false">
3+
<h2>
4+
<%= I18n.t("errors.messages.not_saved",
5+
count: resource.errors.count,
6+
resource: resource.class.model_name.human.downcase)
7+
%>
8+
</h2>
9+
<ul>
10+
<% resource.errors.full_messages.each do |message| %>
11+
<li><%= message %></li>
12+
<% end %>
13+
</ul>
14+
</div>
15+
<% end %>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<%- if controller_name != 'sessions' %>
2+
<%= link_to "Log in", new_session_path(resource_name) %><br />
3+
<% end %>
4+
5+
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
6+
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
7+
<% end %>
8+
9+
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
10+
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
11+
<% end %>
12+
13+
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
14+
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
15+
<% end %>
16+
17+
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
18+
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
19+
<% end %>
20+
21+
<%- if devise_mapping.omniauthable? %>
22+
<%- resource_class.omniauth_providers.each do |provider| %>
23+
<%= button_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), data: { turbo: false } %><br />
24+
<% end %>
25+
<% end %>

0 commit comments

Comments
 (0)