Last active
February 14, 2019 00:20
-
-
Save wkirby/cd64ed0ff3ab365128145edb90b2db67 to your computer and use it in GitHub Desktop.
Migrations and Models for Tripartite Identity in Rails 5.2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
class Account < UUIDRecord | |
# This project uses a tripartite identity pattern | |
# (see http://habitatchronicles.com/2008/10/the-tripartite-identity-pattern/) | |
# This class is the ACCOUNT component. | |
# The other components are User and Profile. | |
# Initializers | |
after_initialize :add_profile, if: :new_record? | |
has_many :users, dependent: :destroy | |
has_many :profiles, dependent: :destroy | |
# TODO: this should be improved to actually be user controlled | |
def primary_user | |
users.first | |
end | |
private | |
def add_profile | |
profiles.build | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gem 'devise' | |
gem 'devise-security' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
class Profile < UUIDRecord | |
# This project uses a tripartite identity pattern | |
# (see http://habitatchronicles.com/2008/10/the-tripartite-identity-pattern/) | |
# This class is the PUBLIC component. | |
# The other components are Account and User. | |
belongs_to :account | |
after_initialize :ensure_account | |
def full_name | |
"#{first_name} #{last_name}" | |
end | |
private | |
def ensure_account | |
build_account if account.blank? | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CreateTripartiteModels < ActiveRecord::Migration[5.2] | |
def change | |
create_table :accounts, id: false do |t| | |
t.string :id, limit: 36, primary_key: true, null: false | |
t.timestamps | |
end | |
create_table :users, id: false do |t| | |
t.string :id, limit: 36, primary_key: true, null: false | |
t.references :account, type: :string, index: true, foreign_key: true | |
## Database authenticatable | |
t.string :email, null: false, default: '' | |
t.string :encrypted_password, null: false, default: '' | |
## Recoverable | |
t.string :reset_password_token | |
t.datetime :reset_password_sent_at | |
## Rememberable | |
t.datetime :remember_created_at | |
## Trackable | |
t.integer :sign_in_count, default: 0, null: false | |
t.datetime :current_sign_in_at | |
t.datetime :last_sign_in_at | |
t.string :current_sign_in_ip | |
t.string :last_sign_in_ip | |
## Confirmable | |
t.string :confirmation_token | |
t.datetime :confirmed_at | |
t.datetime :confirmation_sent_at | |
t.string :unconfirmed_email # Only if using reconfirmable | |
## Lockable | |
t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts | |
t.string :unlock_token # Only if unlock strategy is :email or :both | |
t.datetime :locked_at | |
## Password Expirable | |
t.datetime :password_changed_at | |
t.timestamps null: false | |
end | |
create_table :profiles, id: false do |t| | |
t.string :id, limit: 36, primary_key: true, null: false | |
t.references :account, type: :string, index: true, foreign_key: true | |
t.string :first_name | |
t.string :last_name | |
t.timestamps | |
end | |
## Password Archivable (devise-security) | |
create_table :old_passwords do |t| | |
t.string :encrypted_password, null: false | |
t.string :password_archivable_type, null: false | |
t.string :password_archivable_id, null: false | |
t.string :password_salt | |
t.datetime :created_at | |
end | |
add_index :users, :email, unique: true | |
add_index :users, :reset_password_token, unique: true | |
add_index :users, :confirmation_token, unique: true | |
add_index :users, :unlock_token, unique: true | |
add_index :users, :password_changed_at | |
add_index :old_passwords, [:password_archivable_type, :password_archivable_id], name: :index_password_archivable | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
class User < UUIDRecord | |
# This project uses a tripartite identity pattern | |
# (see http://habitatchronicles.com/2008/10/the-tripartite-identity-pattern/) | |
# This class is the LOGIN component. | |
# The other components are Account and Profile. | |
# devise :database_authenticatable, :registerable, :confirmable, :lockable, | |
# :recoverable, :rememberable, :trackable, :timeoutable, | |
# :validatable, :password_archivable | |
belongs_to :account | |
has_many :profiles, through: :account | |
after_initialize :ensure_account, if: :new_record? | |
private | |
def ensure_account | |
build_account | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
# :nocov: | |
class UUIDRecord < ApplicationRecord | |
self.abstract_class = true | |
after_initialize :set_uuid | |
def set_uuid | |
self.id = SecureRandom.uuid if id.blank? | |
end | |
end | |
# :nocov: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment