Skip to content

Commit e8f63b1

Browse files
committed
Make a basic User model (including secure passwords)
1 parent 45c868f commit e8f63b1

File tree

9 files changed

+111
-1
lines changed

9 files changed

+111
-1
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
44
ruby "3.1.1"
55

66
gem "rails", "7.0.2.3"
7+
gem "bcrypt", "3.1.16"
78
gem "bootstrap-sass", "3.4.1"
89
gem "sassc-rails", "2.1.2"
910
gem "sprockets-rails", "3.4.2"

Gemfile.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ GEM
7171
ansi (1.5.0)
7272
autoprefixer-rails (10.4.2.0)
7373
execjs (~> 2)
74+
bcrypt (3.1.16)
7475
bindex (0.8.1)
7576
bootsnap (1.11.1)
7677
msgpack (~> 1.2)
@@ -269,6 +270,7 @@ PLATFORMS
269270
x86_64-darwin-19
270271

271272
DEPENDENCIES
273+
bcrypt (= 3.1.16)
272274
bootsnap (= 1.11.1)
273275
bootstrap-sass (= 3.4.1)
274276
capybara (= 3.36.0)

app/models/user.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class User < ApplicationRecord
2+
before_save { self.email = email.downcase }
3+
validates :name, presence: true, length: { maximum: 50 }
4+
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
5+
validates :email, presence: true, length: { maximum: 255 },
6+
format: { with: VALID_EMAIL_REGEX },
7+
uniqueness: true
8+
has_secure_password
9+
validates :password, presence: true, length: { minimum: 6 }
10+
end
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class CreateUsers < ActiveRecord::Migration[7.0]
2+
def change
3+
create_table :users do |t|
4+
t.string :name
5+
t.string :email
6+
7+
t.timestamps
8+
end
9+
end
10+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AddIndexToUsersEmail < ActiveRecord::Migration[7.0]
2+
def change
3+
add_index :users, :email, unique: true
4+
end
5+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AddPasswordDigestToUsers < ActiveRecord::Migration[7.0]
2+
def change
3+
add_column :users, :password_digest, :string
4+
end
5+
end

db/schema.rb

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/fixtures/users.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# empty

test/models/user_test.rb

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
require "test_helper"
2+
3+
class UserTest < ActiveSupport::TestCase
4+
5+
def setup
6+
@user = User.new(name: "Example User", email: "[email protected]",
7+
password: "foobar", password_confirmation: "foobar")
8+
end
9+
10+
test "should be valid" do
11+
assert @user.valid?
12+
end
13+
14+
test "name should be present" do
15+
@user.name = ""
16+
assert_not @user.valid?
17+
end
18+
19+
test "email should be present" do
20+
@user.email = " "
21+
assert_not @user.valid?
22+
end
23+
24+
test "name should not be too long" do
25+
@user.name = "a" * 51
26+
assert_not @user.valid?
27+
end
28+
29+
test "email should not be too long" do
30+
@user.email = "a" * 244 + "@example.com"
31+
assert_not @user.valid?
32+
end
33+
34+
test "email validation should accept valid addresses" do
35+
36+
37+
valid_addresses.each do |valid_address|
38+
@user.email = valid_address
39+
assert @user.valid?, "#{valid_address.inspect} should be valid"
40+
end
41+
end
42+
43+
test "email validation should reject invalid addresses" do
44+
invalid_addresses = %w[user@example,com user_at_foo.org user.name@example.
45+
foo@bar_baz.com foo@bar+baz.com]
46+
invalid_addresses.each do |invalid_address|
47+
@user.email = invalid_address
48+
assert_not @user.valid?, "#{invalid_address.inspect} should be invalid"
49+
end
50+
end
51+
52+
test "email addresses should be unique" do
53+
duplicate_user = @user.dup
54+
@user.save
55+
assert_not duplicate_user.valid?
56+
end
57+
58+
test "password should be present (nonblank)" do
59+
@user.password = @user.password_confirmation = " " * 6
60+
assert_not @user.valid?
61+
end
62+
63+
test "password should have a minimum length" do
64+
@user.password = @user.password_confirmation = "a" * 5
65+
assert_not @user.valid?
66+
end
67+
end

0 commit comments

Comments
 (0)