openopus-core-people 1.1.0 → 1.1.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/Rakefile +2 -3
- data/app/models/address.rb +2 -2
- data/app/models/concerns/labelize.rb +26 -0
- data/app/models/email.rb +13 -3
- data/app/models/person.rb +46 -14
- data/app/models/phone.rb +28 -9
- data/app/models/user.rb +14 -14
- data/db/migrate/00000000000005_create_people.rb +1 -0
- data/db/seeds.rb +1 -2
- data/lib/openopus/core/people/engine.rb +0 -1
- data/lib/openopus/core/people/version.rb +1 -1
- data/lib/tasks/openopus/core/people/tasks.rake +44 -0
- metadata +22 -9
- data/app/models/credential.rb +0 -15
- data/db/migrate/00000000000008_create_credentials.rb +0 -13
- data/lib/tasks/openopus/core/people_tasks.rake +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ab650c65f3c0c4bbf10f15ed0a6c0ce275beb9133e6d3ec56577ed043760508
|
4
|
+
data.tar.gz: 94d9e71f0cdb9e4e26a66f0426e8d9b73839c7ce2c1b9e0aee97883331e6fc50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8269bb3d92b704b885ca77b85909c0111ea6a64472aefa646da6c2d114efd033bb0282c150972ac49de813ef101f2ba9ab8b2f679cda9c3d6fd77c4402d11144
|
7
|
+
data.tar.gz: c2cdf46236104f440f932b417ff45f6ff300b629d162dd7d35deada4867ac14a8c224aa53c42b5f2357b60732c46a53c16797e6864232991342b35f006368dd1
|
data/README.md
CHANGED
@@ -17,13 +17,14 @@ Install the gem, run migrations. This will create human structures, from Organi
|
|
17
17
|
Add this line to your application's Gemfile:
|
18
18
|
|
19
19
|
```ruby
|
20
|
-
gem 'openopus-core-people', git: "https://github.com/
|
20
|
+
gem 'openopus-core-people', git: "https://github.com/openopus/openopus-core-people"
|
21
21
|
```
|
22
22
|
|
23
23
|
And then execute:
|
24
24
|
```bash
|
25
25
|
$ bundle install
|
26
|
-
$
|
26
|
+
$ ./bin/rake openopus_core_people_engine:install:migrations
|
27
|
+
$ ./bin/rake db:migrate
|
27
28
|
```
|
28
29
|
|
29
30
|
Or install it yourself as:
|
data/Rakefile
CHANGED
@@ -15,12 +15,11 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
15
15
|
end
|
16
16
|
|
17
17
|
APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
|
18
|
-
load 'rails/tasks/engine.rake'
|
19
|
-
|
18
|
+
# load 'rails/tasks/engine.rake'
|
20
19
|
load 'rails/tasks/statistics.rake'
|
20
|
+
load 'lib/tasks/openopus/core/people/tasks.rake'
|
21
21
|
|
22
22
|
require 'bundler/gem_tasks'
|
23
|
-
|
24
23
|
require 'rake/testtask'
|
25
24
|
|
26
25
|
Rake::TestTask.new(:test) do |t|
|
data/app/models/address.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
# labelize.rb: -*- Ruby -*- DESCRIPTIVE TEXT.
|
2
|
+
#
|
3
|
+
# Copyright (c) 2019 Brian J. Fox Opus Logica, Inc.
|
4
|
+
# Author: Brian J. Fox (bfox@opuslogica.com)
|
5
|
+
# Birthdate: Wed Sep 11 09:37:52 2019.
|
6
|
+
module Labelize
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
included do
|
9
|
+
belongs_to :label, optional: true
|
10
|
+
|
11
|
+
def label
|
12
|
+
db_label = super
|
13
|
+
if not db_label
|
14
|
+
self.label = "Work"
|
15
|
+
db_label = super
|
16
|
+
end
|
17
|
+
|
18
|
+
db_label.value
|
19
|
+
end
|
20
|
+
|
21
|
+
def label=(name)
|
22
|
+
super(Label.get(name))
|
23
|
+
self.label
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/app/models/email.rb
CHANGED
@@ -1,17 +1,27 @@
|
|
1
1
|
class Email < ApplicationRecord
|
2
|
-
|
3
|
-
belongs_to :emailable, polymorphic: true
|
2
|
+
include Labelize
|
3
|
+
belongs_to :emailable, polymorphic: true, optional: true
|
4
4
|
accepts_nested_attributes_for :label
|
5
5
|
before_create :default_label
|
6
|
+
before_save :canonicalize
|
7
|
+
|
8
|
+
VALID_EMAIL_FORMAT_REGEX = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
|
9
|
+
|
10
|
+
validates_format_of :address, with: VALID_EMAIL_FORMAT_REGEX, :on => :create
|
6
11
|
|
7
12
|
def self.canonicalize(addr)
|
8
|
-
addr.strip.downcase if not addr.blank?
|
13
|
+
candidate = addr.strip.downcase if not addr.blank?
|
14
|
+
candidate ||= addr
|
9
15
|
end
|
10
16
|
|
11
17
|
def canonicalize
|
12
18
|
self.address = self.class.canonicalize(self.address)
|
13
19
|
end
|
14
20
|
|
21
|
+
def self.valid_format?(addr)
|
22
|
+
return (addr =~ VALID_EMAIL_FORMAT_REGEX) != nil
|
23
|
+
end
|
24
|
+
|
15
25
|
def default_label
|
16
26
|
self.label = Label.get("Work")
|
17
27
|
end
|
data/app/models/person.rb
CHANGED
@@ -11,12 +11,25 @@ class Person < ApplicationRecord
|
|
11
11
|
accepts_nested_attributes_for :emails
|
12
12
|
|
13
13
|
def self.lookup(name)
|
14
|
+
return nil if not name
|
14
15
|
person = self.find_by(self.name_components(name))
|
15
16
|
person ||= self.includes(:nicknames).joins(:nicknames).find_by("nicknames.nickname" => name)
|
17
|
+
|
18
|
+
# Maybe we're looking up by phone number?
|
16
19
|
if not person
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
+
phone = Phone.where(number: Phone.canonicalize(name)).first rescue nil
|
21
|
+
person = phone.phoneable if phone
|
22
|
+
end
|
23
|
+
|
24
|
+
if not person
|
25
|
+
email = Email.where(emailable_type: self.name.to_s, address: Email.canonicalize(name.downcase)).first
|
26
|
+
person = email.emailable if email
|
27
|
+
end
|
28
|
+
|
29
|
+
if not person
|
30
|
+
# Try hard to find a person by their initials, even if there wasn't a nickname for them.
|
31
|
+
people = self.all.collect {|p| [p.id, p.initials]}
|
32
|
+
|
20
33
|
people.each do |parry|
|
21
34
|
if parry[1] == name.upcase
|
22
35
|
person = self.find(parry[0])
|
@@ -25,11 +38,6 @@ class Person < ApplicationRecord
|
|
25
38
|
end
|
26
39
|
end
|
27
40
|
|
28
|
-
if not person
|
29
|
-
addr = Email.where(emailable_type: self.name.to_s, address: Email.canonicalize(name.downcase)).first
|
30
|
-
person = addr.person.first if addr
|
31
|
-
end
|
32
|
-
|
33
41
|
person
|
34
42
|
end
|
35
43
|
|
@@ -82,7 +90,7 @@ class Person < ApplicationRecord
|
|
82
90
|
result = possibles.include?(text.gsub(/[.]*/, "").downcase) if text.present?
|
83
91
|
end
|
84
92
|
|
85
|
-
def self.name_components(name)
|
93
|
+
def self.name_components(name, transformer=nil)
|
86
94
|
res = {}
|
87
95
|
component = ""
|
88
96
|
components = name.gsub(/,/, " ").gsub(/ /, " ").split(" ") rescue [name]
|
@@ -92,37 +100,56 @@ class Person < ApplicationRecord
|
|
92
100
|
# What kind of thing is this?
|
93
101
|
if is_name_prefix?(component)
|
94
102
|
res[:prefix] = component
|
103
|
+
res[:prefix] = res[:prefix].send(transformer) if res[:prefix] && transformer
|
95
104
|
res[:fname] = components.shift
|
96
105
|
else
|
97
106
|
res[:fname] = component
|
98
107
|
end
|
99
108
|
|
109
|
+
res[:fname] = res[:fname].send(transformer) if res[:fname] && transformer
|
110
|
+
|
100
111
|
# Next up, middle initial or last name.
|
101
112
|
# If only one word remains, that's the last name
|
102
113
|
if components.length == 1
|
103
114
|
res[:lname] = components.shift
|
115
|
+
res[:lname] = res[:lname].send(transformer) if res[:lname] && transformer
|
104
116
|
elsif components.length > 0
|
105
117
|
# At least 2 words remain. We might have middle names, prefixes, suffixes, etc.
|
106
118
|
components.reverse!
|
107
119
|
component = components.shift
|
120
|
+
|
108
121
|
if is_name_suffix?(component)
|
109
122
|
res[:suffix] = component
|
123
|
+
res[:suffix] = res[:suffix].send(transformer) if res[:suffix] && transformer
|
110
124
|
res[:lname] = components.shift
|
111
125
|
else
|
112
126
|
res[:lname] = component
|
113
127
|
end
|
128
|
+
|
129
|
+
res[:lname] = res[:lname].send(transformer) if res[:lname] && transformer
|
130
|
+
|
114
131
|
res[:minitial] = components.shift
|
132
|
+
res[:minitial] = res[:minitial].send(transformer) if res[:minitial] && transformer
|
133
|
+
|
115
134
|
end
|
116
135
|
|
117
136
|
res[:minitial] = res[:minitial].gsub(/[.]/, "") if res[:minitial].present?
|
118
137
|
res
|
119
138
|
end
|
120
|
-
|
139
|
+
|
140
|
+
def initials
|
141
|
+
res = ""
|
142
|
+
res += fname[0] if fname
|
143
|
+
res += minitial[0] if minitial
|
144
|
+
res += lname[0] if lname
|
145
|
+
res.upcase
|
146
|
+
end
|
147
|
+
|
121
148
|
def name
|
122
149
|
components = []
|
123
150
|
|
124
151
|
if prefix.present?
|
125
|
-
if not prefix.include?(".")
|
152
|
+
if not prefix.include?(".") and not prefix =~ /^miss$/i
|
126
153
|
components << "#{prefix}."
|
127
154
|
else
|
128
155
|
components << prefix
|
@@ -231,8 +258,8 @@ class Person < ApplicationRecord
|
|
231
258
|
|
232
259
|
def add_address(address_line, label="Home")
|
233
260
|
if self != self.class.find_by_address(address_line)
|
234
|
-
a = Address.parse(address_line)
|
235
|
-
a.addressable_type = self.class.name
|
261
|
+
a = Address.parse(address_line)
|
262
|
+
a.addressable_type = self.class.name
|
236
263
|
a.label = Label.get(label)
|
237
264
|
a.save
|
238
265
|
addresses << a
|
@@ -240,5 +267,10 @@ class Person < ApplicationRecord
|
|
240
267
|
a = Address.find_by_address(address_line)
|
241
268
|
end
|
242
269
|
|
243
|
-
|
270
|
+
def as_api_json(options={})
|
271
|
+
candidate = self.as_json(options)
|
272
|
+
candidate[:emails] = self.emails.collect {|e| { label: e.label, address: e.address }}
|
273
|
+
candidate[:addresses] = self.addresses.collect {|a| { label: a.label, address: a.address }}
|
274
|
+
candidate
|
275
|
+
end
|
244
276
|
end
|
data/app/models/phone.rb
CHANGED
@@ -1,18 +1,23 @@
|
|
1
|
+
require "phony_rails"
|
2
|
+
|
1
3
|
class Phone < ApplicationRecord
|
2
|
-
|
3
|
-
belongs_to :phoneable, polymorphic: true
|
4
|
+
include Labelize
|
5
|
+
belongs_to :phoneable, polymorphic: true, optional: true
|
4
6
|
before_validation :canonicalize
|
5
7
|
|
6
8
|
def self.canonicalize(digits_and_stuff)
|
7
|
-
canonical = digits_and_stuff
|
8
|
-
canonical.gsub!(" ", "") #remove extra spaces
|
9
|
+
canonical = digits_and_stuff.gsub(" ", "")
|
9
10
|
if canonical
|
10
11
|
canonical = canonical[2..100].strip if canonical.starts_with?("+1")
|
11
|
-
if
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
if self.const_defined?("PhonyRails")
|
13
|
+
canonical = PhonyRails.normalize_number(digits_and_stuff, default_country_code: "US").phony_formatted(format: :international)
|
14
|
+
else
|
15
|
+
if canonical[0] != "+"
|
16
|
+
digits = digits_and_stuff.gsub(/[^0-9]/, "")
|
17
|
+
digits = digits[1..-1] if digits[0] == '1'
|
18
|
+
digits = "805" + digits if digits.length == 7
|
19
|
+
canonical = "(#{digits[0..2]}) #{digits[3..5]}-#{digits[6..10]}"
|
20
|
+
end
|
16
21
|
end
|
17
22
|
end
|
18
23
|
canonical
|
@@ -23,4 +28,18 @@ class Phone < ApplicationRecord
|
|
23
28
|
self.number = self.class.canonicalize(self.number) if self.number
|
24
29
|
end
|
25
30
|
|
31
|
+
def label
|
32
|
+
db_label = super
|
33
|
+
if not db_label
|
34
|
+
self.label = "Work"
|
35
|
+
db_label = super
|
36
|
+
end
|
37
|
+
|
38
|
+
db_label.value
|
39
|
+
end
|
40
|
+
|
41
|
+
def label=(name)
|
42
|
+
super(Label.get(name))
|
43
|
+
self.label
|
44
|
+
end
|
26
45
|
end
|
data/app/models/user.rb
CHANGED
@@ -1,25 +1,18 @@
|
|
1
1
|
class User < ApplicationRecord
|
2
2
|
belongs_to :person
|
3
3
|
accepts_nested_attributes_for :person
|
4
|
-
has_many :credentials, as: :credentialed, dependent: :destroy
|
5
|
-
accepts_nested_attributes_for :credentials
|
6
4
|
has_and_belongs_to_many :organizations
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
delegate
|
13
|
-
delegate :suffix, :suffix, to: :person
|
14
|
-
delegate :emails, :emails=, :email, :email=, to: :person
|
15
|
-
delegate :phones, :phones=, :phone, :phone=, to: :person
|
16
|
-
delegate :addresses, :addresses=, :address, :address=, to: :person
|
17
|
-
delegate :birthdate, :birthdate=, to: :person
|
18
|
-
delegate :age, :age=, to: :person
|
6
|
+
PERSON_ATTR = %w(name fname lname minitial prefix suffix email phone emails phones addresses birthdate age nationality language)
|
7
|
+
PERSON_SYMS = PERSON_ATTR.collect {|x| [x.to_sym, (x + "=").to_sym] }.flatten
|
8
|
+
PERSON_SET = PERSON_SYMS + PERSON_ATTR
|
9
|
+
|
10
|
+
delegate(*PERSON_SYMS, to: :person)
|
19
11
|
|
20
12
|
def self.lookup(item)
|
21
13
|
person = Person.lookup(item)
|
22
|
-
|
14
|
+
this_class = self.name.downcase.to_sym
|
15
|
+
(person.send this_class) if person and person.respond_to?(this_class)
|
23
16
|
end
|
24
17
|
|
25
18
|
def organization=(org)
|
@@ -29,4 +22,11 @@ class User < ApplicationRecord
|
|
29
22
|
def organization
|
30
23
|
self.organizations.order(created_at: :desc).first
|
31
24
|
end
|
25
|
+
|
26
|
+
def assign_attributes(attr)
|
27
|
+
if not attr.keys.to_set.intersection(PERSON_SET).empty?
|
28
|
+
self.person = Person.new
|
29
|
+
end
|
30
|
+
super(attr)
|
31
|
+
end
|
32
32
|
end
|
data/db/seeds.rb
CHANGED
@@ -4,5 +4,4 @@ bfox = User.lookup("bfox@opuslogica.com") ||
|
|
4
4
|
User.create(person_attributes: { email: "bfox@opuslogica.com", name: "Brian Jhan Fox",
|
5
5
|
address: "901 Olive St., Santa Barbara, CA, 93101",
|
6
6
|
phone: "805.555.8642" },
|
7
|
-
organization: opus
|
8
|
-
credentials_attributes: [{ password: "idtmp2tv" }])
|
7
|
+
organization: opus)
|
@@ -0,0 +1,44 @@
|
|
1
|
+
namespace :openopus do
|
2
|
+
namespace :core do
|
3
|
+
namespace :people do
|
4
|
+
desc "Generate one or many random people in your database. Requires 'gem rest-client'. Only for testing!"
|
5
|
+
task :generate_people, [:count] => :environment do |task, args|
|
6
|
+
def generate_person
|
7
|
+
json = ActiveSupport::HashWithIndifferentAccess.new(JSON(RestClient::Request.execute(method: :get, url: 'https://randomuser.me/api?format=json&nat=US').body))
|
8
|
+
jp = json[:results][0]
|
9
|
+
l = jp[:location]
|
10
|
+
a = Address.new
|
11
|
+
a.line1 = l[:street].titleize; a.city = l[:city].titleize; a.state = l[:state].titleize;
|
12
|
+
a.postal = l[:postcode].to_s.upcase; a.country = "US"
|
13
|
+
name = jp[:name]
|
14
|
+
p = Person.create(name: "#{name[:title]} #{name[:first]} #{name[:last]}".titleize,
|
15
|
+
phone: jp[:phone], address: a, email: jp[:email],
|
16
|
+
birthdate: jp[:dob][:date], nationality: jp[:nat])
|
17
|
+
p.picture = jp[:picture][:medium] if p.respond_to?("picture=".to_sym)
|
18
|
+
p.photo = jp[:picture][:medium] if p.respond_to?("photo=".to_sym)
|
19
|
+
p
|
20
|
+
end
|
21
|
+
|
22
|
+
count = args[:count]
|
23
|
+
count ||= 1
|
24
|
+
count.to_i.times do
|
25
|
+
person = generate_person
|
26
|
+
puts("openopus made: #{person.name} of #{person.address.oneline}")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "Generate users from the people in your database that aren't associated with any user. Only for testing!"
|
31
|
+
task :generate_users, [:count] => :environment do |task, args|
|
32
|
+
def generate_user(person)
|
33
|
+
user = User.create(person_id: person.id, status: "generated") if not person.user and not person.email.blank?
|
34
|
+
if user and user.respond_to?(:credentials) and user.credentials.blank?
|
35
|
+
user.credentials.create(password: "password")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
Rake::Task["openopus:core:people:generate_people"].invoke(args[:count]) if not args[:count].blank?
|
40
|
+
Person.all.each { |person| generate_user(person) }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openopus-core-people
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian J. Fox
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 5.2.3
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 5.2.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 3.1.13
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: phony_rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.14'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.14'
|
41
55
|
description: A person can have many email addresses, but this is not usually represented
|
42
56
|
in applications. openopus/core/people creates the database structure, relations,
|
43
57
|
and convenience functions for your application so you don't have to. Just connect
|
@@ -53,7 +67,7 @@ files:
|
|
53
67
|
- Rakefile
|
54
68
|
- app/assets/config/openopus_core_people_manifest.js
|
55
69
|
- app/models/address.rb
|
56
|
-
- app/models/
|
70
|
+
- app/models/concerns/labelize.rb
|
57
71
|
- app/models/email.rb
|
58
72
|
- app/models/label.rb
|
59
73
|
- app/models/nickname.rb
|
@@ -70,14 +84,13 @@ files:
|
|
70
84
|
- db/migrate/00000000000005_create_people.rb
|
71
85
|
- db/migrate/00000000000006_create_organizations.rb
|
72
86
|
- db/migrate/00000000000007_create_users.rb
|
73
|
-
- db/migrate/00000000000008_create_credentials.rb
|
74
87
|
- db/migrate/00000000000009_create_join_table_organizations_users.rb
|
75
88
|
- db/seeds.rb
|
76
89
|
- lib/openopus/core/people.rb
|
77
90
|
- lib/openopus/core/people/engine.rb
|
78
91
|
- lib/openopus/core/people/version.rb
|
79
|
-
- lib/tasks/openopus/core/
|
80
|
-
homepage: https://github.com/
|
92
|
+
- lib/tasks/openopus/core/people/tasks.rake
|
93
|
+
homepage: https://github.com/openopus/openopus-core-people
|
81
94
|
licenses:
|
82
95
|
- MIT
|
83
96
|
metadata:
|
@@ -97,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
110
|
- !ruby/object:Gem::Version
|
98
111
|
version: '0'
|
99
112
|
requirements: []
|
100
|
-
rubygems_version: 3.
|
113
|
+
rubygems_version: 3.1.2
|
101
114
|
signing_key:
|
102
115
|
specification_version: 4
|
103
116
|
summary: Model the real world of people in your application, making user interaction
|
data/app/models/credential.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
class Credential < ApplicationRecord
|
2
|
-
has_secure_password
|
3
|
-
belongs_to :credentialed, polymorphic: true
|
4
|
-
|
5
|
-
# We point to an enail that actually polymorphically belongs to a different thing.
|
6
|
-
# Which is great. So don't declare this to be a polymorphic relationship. It isn't.
|
7
|
-
belongs_to :email
|
8
|
-
before_validation :grab_email_from_credentialed
|
9
|
-
|
10
|
-
# validates :password, length: { minimum: 8 }, on: :create
|
11
|
-
|
12
|
-
def grab_email_from_credentialed
|
13
|
-
self.email ||= self.credentialed.email
|
14
|
-
end
|
15
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
class CreateCredentials < ActiveRecord::Migration[5.2]
|
2
|
-
def change
|
3
|
-
create_table :credentials do |t|
|
4
|
-
t.references :credentialed, polymorphic: true
|
5
|
-
t.references :email, foreign_key: true
|
6
|
-
t.string :password_digest
|
7
|
-
t.string :provider # Like Google, Facebook, etc.
|
8
|
-
t.string :provider_auth # Whatever their auth token looks like.
|
9
|
-
|
10
|
-
t.timestamps
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|