acts_as_human 3.0.2 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +51 -0
- data/.github/workflows/release.yml +18 -0
- data/.rubocop.yml +31 -0
- data/.ruby-version +1 -1
- data/Gemfile +2 -3
- data/README.md +48 -51
- data/Rakefile +5 -3
- data/acts_as_human.gemspec +29 -27
- data/bin/rspec +27 -0
- data/bin/rubocop +27 -0
- data/lefthook.yml +9 -0
- data/lib/acts_as_human/class_methods.rb +23 -28
- data/lib/acts_as_human/instance_methods.rb +9 -36
- data/lib/acts_as_human/name_parser.rb +35 -0
- data/lib/acts_as_human/person_name_validator.rb +11 -0
- data/lib/acts_as_human/version.rb +3 -1
- data/lib/acts_as_human.rb +9 -1
- data/lib/generators/acts_as_human/migration/migration_generator.rb +16 -0
- data/lib/{acts_as_human/generators/migration → generators/acts_as_human/migration/templates}/migration.rb +1 -2
- metadata +46 -61
- data/.travis.yml +0 -5
- data/Guardfile +0 -47
- data/exe/acts_as_human +0 -4
- data/lib/acts_as_human/cli.rb +0 -16
- data/lib/acts_as_human/generators/migration.rb +0 -22
- data/lib/acts_as_human/validations.rb +0 -30
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 2e1b8f04bef566dbf85b27a41a55c22a6bbebf2d8ba6cc6c89926cb22861ef5c
|
|
4
|
+
data.tar.gz: fc902452ab63bca268f8ffd4aa07d09eedfa97619d360e4f6f0bb0498221f121
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7fa2a3766bb4ddbb7d3a11774ae3fa790a5e1c35a7b55761562466f01bbe8c5c9bf3631a7fbe438137439f336e6f68b34be5f379b3f206531dbf74e16204e316
|
|
7
|
+
data.tar.gz: 7b4baae82d36987e518e3fb2707c5b2cfb69837017af6d9caa45f6e9d321546883d5e51f86b4f400acc106c591b950bbb6f934d7f3000cb3c1a2a2d3297fe866
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
ruby: ["3.3", "3.4"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- uses: ruby/setup-ruby@v1
|
|
20
|
+
with:
|
|
21
|
+
ruby-version: ${{ matrix.ruby }}
|
|
22
|
+
bundler-cache: true
|
|
23
|
+
|
|
24
|
+
- run: bundle exec rspec
|
|
25
|
+
|
|
26
|
+
audit:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v4
|
|
31
|
+
|
|
32
|
+
- uses: ruby/setup-ruby@v1
|
|
33
|
+
with:
|
|
34
|
+
ruby-version: "3.4"
|
|
35
|
+
bundler-cache: true
|
|
36
|
+
|
|
37
|
+
- run: gem install bundler-audit
|
|
38
|
+
- run: bundle-audit check --update
|
|
39
|
+
|
|
40
|
+
lint:
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v4
|
|
45
|
+
|
|
46
|
+
- uses: ruby/setup-ruby@v1
|
|
47
|
+
with:
|
|
48
|
+
ruby-version: "3.4"
|
|
49
|
+
bundler-cache: true
|
|
50
|
+
|
|
51
|
+
- run: bundle exec rubocop
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ['v*']
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
release:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
id-token: write
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: ruby/setup-ruby@v1
|
|
15
|
+
with:
|
|
16
|
+
ruby-version: "3.4"
|
|
17
|
+
bundler-cache: true
|
|
18
|
+
- uses: rubygems/release-gem@v1
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
plugins:
|
|
2
|
+
- rubocop-rspec
|
|
3
|
+
|
|
4
|
+
AllCops:
|
|
5
|
+
TargetRubyVersion: 3.3
|
|
6
|
+
NewCops: enable
|
|
7
|
+
SuggestExtensions: false
|
|
8
|
+
Exclude:
|
|
9
|
+
- "bin/**/*"
|
|
10
|
+
- "vendor/**/*"
|
|
11
|
+
- "lib/generators/**/*.rb"
|
|
12
|
+
|
|
13
|
+
Style/Documentation:
|
|
14
|
+
Enabled: false
|
|
15
|
+
|
|
16
|
+
Gemspec/DevelopmentDependencies:
|
|
17
|
+
Enabled: false
|
|
18
|
+
|
|
19
|
+
Metrics/BlockLength:
|
|
20
|
+
Exclude:
|
|
21
|
+
- "spec/**/*"
|
|
22
|
+
|
|
23
|
+
RSpec/SpecFilePathFormat:
|
|
24
|
+
Exclude:
|
|
25
|
+
- "spec/generators/**/*"
|
|
26
|
+
|
|
27
|
+
RSpec/MultipleExpectations:
|
|
28
|
+
Enabled: false
|
|
29
|
+
|
|
30
|
+
RSpec/ExampleLength:
|
|
31
|
+
Enabled: false
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
ruby-
|
|
1
|
+
ruby-3.4.8
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,72 +1,69 @@
|
|
|
1
|
-
|
|
1
|
+
[](https://github.com/brentgreeff/acts_as_human/actions/workflows/ci.yml)
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
# t.string "first_name"
|
|
5
|
-
# t.string "middle_names"
|
|
6
|
-
# t.string "last_name"
|
|
7
|
-
|
|
8
|
-
acts_as_human
|
|
9
|
-
end
|
|
3
|
+
# acts_as_human
|
|
10
4
|
|
|
11
|
-
|
|
12
|
-
`user = User.new(first_name: 'Brent', last_name: 'Greeff')`
|
|
13
|
-
|
|
14
|
-
You can then read the full_name
|
|
5
|
+
Adds `full_name` / `full_name=` to an ActiveRecord model, splitting a single input into `first_name`, `middle_names`, and `last_name` with validations.
|
|
15
6
|
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
```ruby
|
|
8
|
+
class User < ActiveRecord::Base
|
|
9
|
+
acts_as_human
|
|
10
|
+
end
|
|
11
|
+
```
|
|
18
12
|
|
|
19
|
-
|
|
20
|
-
`user = User.new(full_name: "Brent Wicked Middle Names Greeff")`
|
|
21
|
-
|
|
22
|
-
You can then read the individual names:
|
|
13
|
+
## Installation
|
|
23
14
|
|
|
24
|
-
|
|
25
|
-
|
|
15
|
+
```ruby
|
|
16
|
+
# Gemfile
|
|
17
|
+
gem 'acts_as_human'
|
|
18
|
+
```
|
|
26
19
|
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
```bash
|
|
21
|
+
bundle install
|
|
22
|
+
rails generate acts_as_human:migration users
|
|
23
|
+
rake db:migrate
|
|
24
|
+
```
|
|
29
25
|
|
|
30
|
-
|
|
31
|
-
=> "Wicked Middle Names"
|
|
26
|
+
Change `users` to the name of your table.
|
|
32
27
|
|
|
28
|
+
## Usage
|
|
33
29
|
|
|
34
|
-
|
|
35
|
-
Saves to 3 separate fields:
|
|
36
|
-
first_name, middle_names and last_name allowing you to easily display their name
|
|
37
|
-
in different formats in different places.
|
|
30
|
+
Assign names individually:
|
|
38
31
|
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
```ruby
|
|
33
|
+
user = User.new(first_name: 'Brent', last_name: 'Greeff')
|
|
34
|
+
user.full_name # => "Brent Greeff"
|
|
35
|
+
```
|
|
41
36
|
|
|
42
|
-
|
|
37
|
+
Or assign via a single input:
|
|
43
38
|
|
|
44
|
-
|
|
39
|
+
```ruby
|
|
40
|
+
user = User.new(full_name: 'Brent Wicked Middle Names Greeff')
|
|
41
|
+
user.first_name # => "Brent"
|
|
42
|
+
user.middle_names # => "Wicked Middle Names"
|
|
43
|
+
user.last_name # => "Greeff"
|
|
44
|
+
```
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
## Options
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
```ruby
|
|
49
|
+
acts_as_human require_last_name: false
|
|
50
|
+
```
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
first_name, last_name and middle_names columns in the database.
|
|
52
|
+
## Validations
|
|
52
53
|
|
|
53
|
-
|
|
54
|
+
- `first_name` is required
|
|
55
|
+
- `last_name` is required (unless `require_last_name: false`)
|
|
56
|
+
- Each field is limited to 40 characters
|
|
57
|
+
- Non-name characters (`< > & /`) are rejected
|
|
54
58
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
Change "users" to the name of your existing table.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
## Contributing
|
|
59
|
+
## Development
|
|
61
60
|
|
|
62
|
-
|
|
61
|
+
```bash
|
|
62
|
+
bundle install
|
|
63
|
+
bundle exec lefthook install
|
|
64
|
+
bundle exec rspec
|
|
65
|
+
```
|
|
63
66
|
|
|
64
67
|
## License
|
|
65
68
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
## Development
|
|
69
|
-
|
|
70
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
71
|
-
|
|
72
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
69
|
+
MIT
|
data/Rakefile
CHANGED
data/acts_as_human.gemspec
CHANGED
|
@@ -1,33 +1,35 @@
|
|
|
1
|
-
#
|
|
2
|
-
lib = File.expand_path("../lib", __FILE__)
|
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
-
require "acts_as_human/version"
|
|
1
|
+
# frozen_string_literal: true
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
s.name = %q{acts_as_human}
|
|
8
|
-
s.version = ActsAsHuman::VERSION
|
|
9
|
-
s.authors = ["Brent"]
|
|
10
|
-
s.email = ["brentgreeff@gmail.com"]
|
|
3
|
+
require_relative 'lib/acts_as_human/version'
|
|
11
4
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'acts_as_human'
|
|
7
|
+
spec.version = ActsAsHuman::VERSION
|
|
8
|
+
spec.authors = ['Brent Greeff']
|
|
9
|
+
spec.email = ['brentgreeff@gmail.com']
|
|
10
|
+
spec.summary = 'Rails plugin to handle first_name, middle_names and last_name combinations.'
|
|
11
|
+
spec.homepage = 'https://github.com/brentgreeff/acts_as_human'
|
|
12
|
+
spec.license = 'MIT'
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
f.match(%r{^(test|spec|features)/})
|
|
18
|
-
end
|
|
19
|
-
s.bindir = "exe"
|
|
20
|
-
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
21
|
-
s.require_paths = ["lib"]
|
|
14
|
+
spec.required_ruby_version = '>= 3.3'
|
|
22
15
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
spec.metadata = {
|
|
17
|
+
'source_code_uri' => 'https://github.com/brentgreeff/acts_as_human',
|
|
18
|
+
'rubygems_mfa_required' => 'true'
|
|
19
|
+
}
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
21
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:spec|test|features)/}) }
|
|
22
|
+
spec.bindir = 'exe'
|
|
23
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
24
|
+
spec.require_paths = ['lib']
|
|
25
|
+
|
|
26
|
+
spec.add_dependency 'activerecord', '>= 7.0'
|
|
27
|
+
spec.add_dependency 'railties', '>= 7.0'
|
|
28
|
+
|
|
29
|
+
spec.add_development_dependency 'bundler-audit'
|
|
30
|
+
spec.add_development_dependency 'lefthook'
|
|
31
|
+
spec.add_development_dependency 'rspec-rails'
|
|
32
|
+
spec.add_development_dependency 'rubocop'
|
|
33
|
+
spec.add_development_dependency 'rubocop-rspec'
|
|
34
|
+
spec.add_development_dependency 'sqlite3'
|
|
33
35
|
end
|
data/bin/rspec
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# This file was generated by Bundler.
|
|
6
|
+
#
|
|
7
|
+
# The application 'rspec' is installed as part of a gem, and
|
|
8
|
+
# this file is here to facilitate running it.
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
|
12
|
+
|
|
13
|
+
bundle_binstub = File.expand_path("bundle", __dir__)
|
|
14
|
+
|
|
15
|
+
if File.file?(bundle_binstub)
|
|
16
|
+
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
|
|
17
|
+
load(bundle_binstub)
|
|
18
|
+
else
|
|
19
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
|
20
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
require "rubygems"
|
|
25
|
+
require "bundler/setup"
|
|
26
|
+
|
|
27
|
+
load Gem.bin_path("rspec-core", "rspec")
|
data/bin/rubocop
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# This file was generated by Bundler.
|
|
6
|
+
#
|
|
7
|
+
# The application 'rubocop' is installed as part of a gem, and
|
|
8
|
+
# this file is here to facilitate running it.
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
|
12
|
+
|
|
13
|
+
bundle_binstub = File.expand_path("bundle", __dir__)
|
|
14
|
+
|
|
15
|
+
if File.file?(bundle_binstub)
|
|
16
|
+
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
|
|
17
|
+
load(bundle_binstub)
|
|
18
|
+
else
|
|
19
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
|
20
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
require "rubygems"
|
|
25
|
+
require "bundler/setup"
|
|
26
|
+
|
|
27
|
+
load Gem.bin_path("rubocop", "rubocop")
|
data/lefthook.yml
ADDED
|
@@ -1,41 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActsAs
|
|
2
4
|
module Human
|
|
3
5
|
module ClassMethods
|
|
4
|
-
|
|
5
|
-
def acts_as_human(options={})
|
|
6
|
+
def acts_as_human(options = {})
|
|
6
7
|
cattr_accessor :require_last_name
|
|
8
|
+
self.require_last_name = options.fetch(:require_last_name, true)
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
class_eval do
|
|
15
|
-
validates_presence_of :first_name, message: 'first name is required'
|
|
16
|
-
validates_length_of :first_name, maximum: 40,
|
|
17
|
-
message: 'first name is too long (max 40 characters)'
|
|
18
|
-
|
|
19
|
-
validates_as_person_name :first_name
|
|
20
|
-
|
|
21
|
-
validates_length_of :middle_names, maximum: 40,
|
|
22
|
-
allow_blank: true,
|
|
23
|
-
message: 'middle names are too long (max 40 characters)'
|
|
10
|
+
validate_first_name
|
|
11
|
+
validate_middle_names
|
|
12
|
+
validate_last_name
|
|
13
|
+
end
|
|
24
14
|
|
|
25
|
-
|
|
15
|
+
private
|
|
26
16
|
|
|
27
|
-
|
|
28
|
-
|
|
17
|
+
def validate_first_name
|
|
18
|
+
validates :first_name, presence: { message: 'first name is required' },
|
|
19
|
+
length: { maximum: 40, message: 'first name is too long (max 40 characters)' },
|
|
20
|
+
person_name: true
|
|
21
|
+
end
|
|
29
22
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
def validate_middle_names
|
|
24
|
+
validates :middle_names, length: { maximum: 40, message: 'middle names are too long (max 40 characters)' },
|
|
25
|
+
person_name: true,
|
|
26
|
+
allow_nil: true
|
|
27
|
+
end
|
|
33
28
|
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
def validate_last_name
|
|
30
|
+
validates :last_name, presence: { message: 'last name is required', if: -> { require_last_name } },
|
|
31
|
+
length: { maximum: 40, message: 'last name is too long (max 40 characters)' },
|
|
32
|
+
person_name: true
|
|
36
33
|
end
|
|
37
34
|
end
|
|
38
35
|
end
|
|
39
36
|
end
|
|
40
|
-
|
|
41
|
-
ActiveRecord::Base.send(:extend, ActsAs::Human::ClassMethods)
|
|
@@ -1,48 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActsAs
|
|
2
4
|
module Human
|
|
3
|
-
|
|
4
5
|
module InstanceMethods
|
|
5
6
|
def full_name
|
|
6
|
-
return '' if first_name.blank?
|
|
7
|
-
|
|
7
|
+
return '' if first_name.blank? && last_name.blank?
|
|
8
8
|
return "#{first_name} #{last_name}" if middle_names.blank?
|
|
9
|
-
return "#{first_name} #{middle_names} #{last_name}"
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def full_name=(names)
|
|
13
|
-
names_array = names.titlecase.split
|
|
14
|
-
|
|
15
|
-
self.first_name = names_array.first
|
|
16
|
-
return if names_array.size < 2
|
|
17
|
-
|
|
18
|
-
self.last_name = get_last_name(names_array)
|
|
19
9
|
|
|
20
|
-
|
|
10
|
+
"#{first_name} #{middle_names} #{last_name}"
|
|
21
11
|
end
|
|
22
12
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
names_array << "#{names_array.pop} #{surname}"
|
|
29
|
-
end
|
|
30
|
-
names_array.last
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def assign_middle_names(names_array)
|
|
34
|
-
if names_array.size > 2
|
|
35
|
-
self.middle_names = get_middle_names(names_array)
|
|
36
|
-
else
|
|
37
|
-
self.middle_names = nil
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def get_middle_names(names_array)
|
|
42
|
-
names_array[1..(names_array.size-2)].join(' ')
|
|
13
|
+
def full_name=(value)
|
|
14
|
+
parsed = NameParser.new(value)
|
|
15
|
+
self.first_name = parsed.first_name
|
|
16
|
+
self.last_name = parsed.last_name
|
|
17
|
+
self.middle_names = parsed.middle_names
|
|
43
18
|
end
|
|
44
19
|
end
|
|
45
20
|
end
|
|
46
21
|
end
|
|
47
|
-
|
|
48
|
-
ActiveRecord::Base.send(:include, ActsAs::Human::InstanceMethods)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActsAs
|
|
4
|
+
module Human
|
|
5
|
+
class NameParser
|
|
6
|
+
attr_reader :first_name, :middle_names, :last_name
|
|
7
|
+
|
|
8
|
+
def initialize(full_name)
|
|
9
|
+
parts = full_name.titlecase.split
|
|
10
|
+
@first_name = parts.first
|
|
11
|
+
@last_name = extract_last_name(parts)
|
|
12
|
+
@middle_names = extract_middle_names(parts)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def extract_last_name(parts)
|
|
18
|
+
return nil if parts.size < 2
|
|
19
|
+
|
|
20
|
+
if parts.size > 2 && parts[-2] == 'Mc'
|
|
21
|
+
"#{parts[-2]} #{parts[-1]}"
|
|
22
|
+
else
|
|
23
|
+
parts.last
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def extract_middle_names(parts)
|
|
28
|
+
return nil if parts.size < 3
|
|
29
|
+
|
|
30
|
+
upper = parts[-2] == 'Mc' ? -3 : -2
|
|
31
|
+
parts[1..upper].join(' ')
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class PersonNameValidator < ActiveModel::EachValidator
|
|
4
|
+
ACCEPTABLE = %r{\A[^[:cntrl:]\\<>/&]*\z}
|
|
5
|
+
|
|
6
|
+
def validate_each(record, attribute, value)
|
|
7
|
+
return if value.nil?
|
|
8
|
+
|
|
9
|
+
record.errors.add(attribute, 'some characters in your name are not allowed') unless value.match?(ACCEPTABLE)
|
|
10
|
+
end
|
|
11
|
+
end
|
data/lib/acts_as_human.rb
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'acts_as_human/person_name_validator'
|
|
4
|
+
require 'acts_as_human/name_parser'
|
|
2
5
|
require 'acts_as_human/instance_methods'
|
|
3
6
|
require 'acts_as_human/class_methods'
|
|
7
|
+
|
|
8
|
+
ActiveSupport.on_load(:active_record) do
|
|
9
|
+
include ActsAs::Human::InstanceMethods
|
|
10
|
+
extend ActsAs::Human::ClassMethods
|
|
11
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActsAsHuman
|
|
4
|
+
module Generators
|
|
5
|
+
class MigrationGenerator < Rails::Generators::NamedBase
|
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
|
7
|
+
|
|
8
|
+
desc 'Generates a migration to add first_name, middle_names, and last_name to a table.'
|
|
9
|
+
|
|
10
|
+
def create_migration
|
|
11
|
+
timestamp = Time.now.utc.strftime('%Y%m%d%H%M%S')
|
|
12
|
+
template 'migration.rb', "db/migrate/#{timestamp}_add_names_to_#{file_name}.rb"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
class AddNamesTo<%=
|
|
2
|
-
|
|
1
|
+
class AddNamesTo<%= class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
|
|
3
2
|
def change
|
|
4
3
|
add_column :<%= table_name %>, :first_name, :string
|
|
5
4
|
add_column :<%= table_name %>, :middle_names, :string
|
metadata
CHANGED
|
@@ -1,45 +1,44 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: acts_as_human
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 4.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
- Brent
|
|
8
|
-
autorequire:
|
|
7
|
+
- Brent Greeff
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
13
|
+
name: activerecord
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
|
-
- - "
|
|
16
|
+
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
20
|
-
type: :
|
|
18
|
+
version: '7.0'
|
|
19
|
+
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
|
-
- - "
|
|
23
|
+
- - ">="
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
25
|
+
version: '7.0'
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
27
|
+
name: railties
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
30
29
|
requirements:
|
|
31
|
-
- - "
|
|
30
|
+
- - ">="
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
34
|
-
type: :
|
|
32
|
+
version: '7.0'
|
|
33
|
+
type: :runtime
|
|
35
34
|
prerelease: false
|
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
36
|
requirements:
|
|
38
|
-
- - "
|
|
37
|
+
- - ">="
|
|
39
38
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
39
|
+
version: '7.0'
|
|
41
40
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
41
|
+
name: bundler-audit
|
|
43
42
|
requirement: !ruby/object:Gem::Requirement
|
|
44
43
|
requirements:
|
|
45
44
|
- - ">="
|
|
@@ -53,49 +52,35 @@ dependencies:
|
|
|
53
52
|
- !ruby/object:Gem::Version
|
|
54
53
|
version: '0'
|
|
55
54
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - "~>"
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: '1.15'
|
|
62
|
-
type: :development
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - "~>"
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: '1.15'
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: rake
|
|
55
|
+
name: lefthook
|
|
71
56
|
requirement: !ruby/object:Gem::Requirement
|
|
72
57
|
requirements:
|
|
73
|
-
- - "
|
|
58
|
+
- - ">="
|
|
74
59
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
60
|
+
version: '0'
|
|
76
61
|
type: :development
|
|
77
62
|
prerelease: false
|
|
78
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
64
|
requirements:
|
|
80
|
-
- - "
|
|
65
|
+
- - ">="
|
|
81
66
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
67
|
+
version: '0'
|
|
83
68
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name: rspec
|
|
69
|
+
name: rspec-rails
|
|
85
70
|
requirement: !ruby/object:Gem::Requirement
|
|
86
71
|
requirements:
|
|
87
|
-
- - "
|
|
72
|
+
- - ">="
|
|
88
73
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '
|
|
74
|
+
version: '0'
|
|
90
75
|
type: :development
|
|
91
76
|
prerelease: false
|
|
92
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
78
|
requirements:
|
|
94
|
-
- - "
|
|
79
|
+
- - ">="
|
|
95
80
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '
|
|
81
|
+
version: '0'
|
|
97
82
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name:
|
|
83
|
+
name: rubocop
|
|
99
84
|
requirement: !ruby/object:Gem::Requirement
|
|
100
85
|
requirements:
|
|
101
86
|
- - ">="
|
|
@@ -109,7 +94,7 @@ dependencies:
|
|
|
109
94
|
- !ruby/object:Gem::Version
|
|
110
95
|
version: '0'
|
|
111
96
|
- !ruby/object:Gem::Dependency
|
|
112
|
-
name:
|
|
97
|
+
name: rubocop-rspec
|
|
113
98
|
requirement: !ruby/object:Gem::Requirement
|
|
114
99
|
requirements:
|
|
115
100
|
- - ">="
|
|
@@ -123,7 +108,7 @@ dependencies:
|
|
|
123
108
|
- !ruby/object:Gem::Version
|
|
124
109
|
version: '0'
|
|
125
110
|
- !ruby/object:Gem::Dependency
|
|
126
|
-
name:
|
|
111
|
+
name: sqlite3
|
|
127
112
|
requirement: !ruby/object:Gem::Requirement
|
|
128
113
|
requirements:
|
|
129
114
|
- - ">="
|
|
@@ -136,41 +121,43 @@ dependencies:
|
|
|
136
121
|
- - ">="
|
|
137
122
|
- !ruby/object:Gem::Version
|
|
138
123
|
version: '0'
|
|
139
|
-
description:
|
|
140
124
|
email:
|
|
141
125
|
- brentgreeff@gmail.com
|
|
142
|
-
executables:
|
|
143
|
-
- acts_as_human
|
|
126
|
+
executables: []
|
|
144
127
|
extensions: []
|
|
145
128
|
extra_rdoc_files: []
|
|
146
129
|
files:
|
|
130
|
+
- ".github/workflows/ci.yml"
|
|
131
|
+
- ".github/workflows/release.yml"
|
|
147
132
|
- ".gitignore"
|
|
148
133
|
- ".rspec"
|
|
134
|
+
- ".rubocop.yml"
|
|
149
135
|
- ".ruby-gemset"
|
|
150
136
|
- ".ruby-version"
|
|
151
|
-
- ".travis.yml"
|
|
152
137
|
- Gemfile
|
|
153
|
-
- Guardfile
|
|
154
138
|
- LICENSE.txt
|
|
155
139
|
- README.md
|
|
156
140
|
- Rakefile
|
|
157
141
|
- acts_as_human.gemspec
|
|
158
142
|
- bin/console
|
|
143
|
+
- bin/rspec
|
|
144
|
+
- bin/rubocop
|
|
159
145
|
- bin/setup
|
|
160
|
-
-
|
|
146
|
+
- lefthook.yml
|
|
161
147
|
- lib/acts_as_human.rb
|
|
162
148
|
- lib/acts_as_human/class_methods.rb
|
|
163
|
-
- lib/acts_as_human/cli.rb
|
|
164
|
-
- lib/acts_as_human/generators/migration.rb
|
|
165
|
-
- lib/acts_as_human/generators/migration/migration.rb
|
|
166
149
|
- lib/acts_as_human/instance_methods.rb
|
|
167
|
-
- lib/acts_as_human/
|
|
150
|
+
- lib/acts_as_human/name_parser.rb
|
|
151
|
+
- lib/acts_as_human/person_name_validator.rb
|
|
168
152
|
- lib/acts_as_human/version.rb
|
|
169
|
-
|
|
153
|
+
- lib/generators/acts_as_human/migration/migration_generator.rb
|
|
154
|
+
- lib/generators/acts_as_human/migration/templates/migration.rb
|
|
155
|
+
homepage: https://github.com/brentgreeff/acts_as_human
|
|
170
156
|
licenses:
|
|
171
157
|
- MIT
|
|
172
|
-
metadata:
|
|
173
|
-
|
|
158
|
+
metadata:
|
|
159
|
+
source_code_uri: https://github.com/brentgreeff/acts_as_human
|
|
160
|
+
rubygems_mfa_required: 'true'
|
|
174
161
|
rdoc_options: []
|
|
175
162
|
require_paths:
|
|
176
163
|
- lib
|
|
@@ -178,16 +165,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
178
165
|
requirements:
|
|
179
166
|
- - ">="
|
|
180
167
|
- !ruby/object:Gem::Version
|
|
181
|
-
version: '
|
|
168
|
+
version: '3.3'
|
|
182
169
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
183
170
|
requirements:
|
|
184
171
|
- - ">="
|
|
185
172
|
- !ruby/object:Gem::Version
|
|
186
173
|
version: '0'
|
|
187
174
|
requirements: []
|
|
188
|
-
|
|
189
|
-
rubygems_version: 2.6.13
|
|
190
|
-
signing_key:
|
|
175
|
+
rubygems_version: 3.6.9
|
|
191
176
|
specification_version: 4
|
|
192
177
|
summary: Rails plugin to handle first_name, middle_names and last_name combinations.
|
|
193
178
|
test_files: []
|
data/.travis.yml
DELETED
data/Guardfile
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# A sample Guardfile
|
|
2
|
-
# More info at https://github.com/guard/guard#readme
|
|
3
|
-
|
|
4
|
-
## Uncomment and set this to only include directories you want to watch
|
|
5
|
-
# directories %w(app lib config test spec features) \
|
|
6
|
-
# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
|
7
|
-
|
|
8
|
-
## Note: if you are using the `directories` clause above and you are not
|
|
9
|
-
## watching the project directory ('.'), then you will want to move
|
|
10
|
-
## the Guardfile to a watched dir and symlink it back, e.g.
|
|
11
|
-
#
|
|
12
|
-
# $ mkdir config
|
|
13
|
-
# $ mv Guardfile config/
|
|
14
|
-
# $ ln -s config/Guardfile .
|
|
15
|
-
#
|
|
16
|
-
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
|
17
|
-
|
|
18
|
-
# Note: The cmd option is now required due to the increasing number of ways
|
|
19
|
-
# rspec may be run, below are examples of the most common uses.
|
|
20
|
-
# * bundler: 'bundle exec rspec'
|
|
21
|
-
# * bundler binstubs: 'bin/rspec'
|
|
22
|
-
# * spring: 'bin/rspec' (This will use spring if running and you have
|
|
23
|
-
# installed the spring binstubs per the docs)
|
|
24
|
-
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
|
25
|
-
# * 'just' rspec: 'rspec'
|
|
26
|
-
|
|
27
|
-
guard :rspec, cmd: "bundle exec rspec" do
|
|
28
|
-
require "guard/rspec/dsl"
|
|
29
|
-
dsl = Guard::RSpec::Dsl.new(self)
|
|
30
|
-
|
|
31
|
-
clearing :on
|
|
32
|
-
|
|
33
|
-
# RSpec files
|
|
34
|
-
rspec = dsl.rspec
|
|
35
|
-
watch(rspec.spec_helper) { rspec.spec_dir }
|
|
36
|
-
watch(rspec.spec_support) { rspec.spec_dir }
|
|
37
|
-
watch(rspec.spec_files)
|
|
38
|
-
|
|
39
|
-
watch(%r{^lib/acts_as_human/(.+)\.rb}) do
|
|
40
|
-
"spec/acts_as_human_spec.rb"
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Ruby files
|
|
44
|
-
ruby = dsl.ruby
|
|
45
|
-
dsl.watch_spec_files_for(ruby.lib_files)
|
|
46
|
-
|
|
47
|
-
end
|
data/exe/acts_as_human
DELETED
data/lib/acts_as_human/cli.rb
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
require 'active_support'
|
|
2
|
-
require 'active_record'
|
|
3
|
-
require 'acts_as_human'
|
|
4
|
-
require 'thor'
|
|
5
|
-
require 'acts_as_human/generators/migration'
|
|
6
|
-
|
|
7
|
-
module ActsAsHuman
|
|
8
|
-
|
|
9
|
-
class CLI < Thor
|
|
10
|
-
|
|
11
|
-
desc "migration", "Generates migration to add name fields"
|
|
12
|
-
def migration( table_name )
|
|
13
|
-
Generators::Migration.start( [table_name] )
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
module ActsAsHuman
|
|
2
|
-
|
|
3
|
-
module Generators
|
|
4
|
-
|
|
5
|
-
class Migration < Thor::Group
|
|
6
|
-
include Thor::Actions
|
|
7
|
-
|
|
8
|
-
argument :table_name, type: :string
|
|
9
|
-
|
|
10
|
-
def self.source_root
|
|
11
|
-
File.dirname(__FILE__) + '/migration'
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def copy_migration
|
|
15
|
-
time = ActiveRecord::Migration.next_migration_number(1)
|
|
16
|
-
file = "db/migrate/#{time}_add_names_to_#{table_name}.rb"
|
|
17
|
-
template("migration.rb", file)
|
|
18
|
-
puts 'Migration created'
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
module ActsAs
|
|
2
|
-
module Human
|
|
3
|
-
mattr_accessor :acceptable_name, :bad_name_message
|
|
4
|
-
|
|
5
|
-
self.acceptable_name = /\A[^[:cntrl:]\\<>\/&]*\z/
|
|
6
|
-
self.bad_name_message = "some characters in your name are not allowed".freeze
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
module ActiveRecord
|
|
11
|
-
module Validations
|
|
12
|
-
module ClassMethods
|
|
13
|
-
|
|
14
|
-
def validates_as_person_name(*attr_names)
|
|
15
|
-
config = {
|
|
16
|
-
with: ActsAs::Human.acceptable_name,
|
|
17
|
-
message: ActsAs::Human.bad_name_message
|
|
18
|
-
}
|
|
19
|
-
check_format(attr_names, config)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
private
|
|
23
|
-
|
|
24
|
-
def check_format(attr_names, config)
|
|
25
|
-
config.update(attr_names.pop) if attr_names.last.is_a?(Hash)
|
|
26
|
-
validates_format_of attr_names, config
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|