Skip to content

Commit

Permalink
Generate a person model
Browse files Browse the repository at this point in the history
A person represents a flesh-and-blood human in the system, and should be
the core data model representing _most_ actors in the system.

Eventually, we will want to attach the filled form results to a person
record, and Accounts should belong to a person to grant the ability to
log into the system.

Note that this table explicitly does _not_ include any authentication
related material.  tokens generated for things like magic login, or
authorization credentials for regular users, should exist in their own
dedicated classes.  I'll follow up with an email+token based auth flow
implementation later.
  • Loading branch information
cflipse committed Jun 9, 2024
1 parent 9b039ab commit 97f2e56
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 1 deletion.
1 change: 1 addition & 0 deletions app/models/concerns/avatarable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module Avatarable
included do
has_one_attached :avatar

# TODO: move these validation strings to a locale file
validates :avatar, content_type: {in: ["image/png", "image/jpeg"],
message: "must be PNG or JPEG"},
size: {between: 10.kilobyte..1.megabytes,
Expand Down
27 changes: 27 additions & 0 deletions app/models/person.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# == Schema Information
#
# Table name: people
#
# id :bigint not null, primary key
# email :string not null
# name :string not null
# phone :string
# created_at :datetime not null
# updated_at :datetime not null
# organization_id :bigint not null
#
# Indexes
#
# index_people_on_email (email)
# index_people_on_organization_id (organization_id)
#
# Foreign Keys
#
# fk_rails_... (organization_id => organizations.id)
#
class Person < ApplicationRecord
include Avatarable

validates :name, presence: true
validates :email, presence: true
end
12 changes: 12 additions & 0 deletions db/migrate/20240609170030_create_people.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class CreatePeople < ActiveRecord::Migration[7.1]
def change
create_table :people do |t|
t.references :organization, null: false, foreign_key: true
t.string :name, null: false
t.string :email, null: false, index: true
t.string :phone

t.timestamps
end
end
end
14 changes: 13 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions test/factories/people.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FactoryBot.define do
factory :person do

end
end
62 changes: 62 additions & 0 deletions test/models/person_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
require "test_helper"

class PersonTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end

context "associations" do

end

context "validations" do
should validate_presence_of(:name)
should validate_presence_of(:email)
should_not validate_presence_of(:phone)
end

context "#avatar" do
should "attach an avatar" do
file = load_file("test.png")

assert_nothing_raised do
subject.avatar.attach(io: file, filename: "test.png")
end
end

context "validations" do
should "error if the avatar is too big" do
file = load_file("test.png")
file.stubs(:size).returns(5.megabytes)

subject.avatar.attach(io: file, filename: "test.png")

refute subject.valid?
assert_includes subject.errors[:avatar], "size must be between 10kb and 1Mb"
end

should "error if the avatar is too small" do
file = load_file("test.png")
file.stubs(:size).returns(5.kilobytes)

subject.avatar.attach(io: file, filename: "test.png")

refute subject.valid?
assert_includes subject.errors[:avatar], "size must be between 10kb and 1Mb"
end

should "error if the avatar is not an image" do
file = load_file("blank.pdf")

subject.avatar.attach(io: file, filename: "test.png")

refute subject.valid?
assert_includes subject.errors[:avatar], "must be PNG or JPEG"
end
end
end

def load_file(file_name)
File.open Rails.root.join("test/fixtures/files", file_name)
end
end

0 comments on commit 97f2e56

Please sign in to comment.