active_form_model 0.3.0 → 0.4.1
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 +4 -4
- data/.github/workflows/main.yml +19 -0
- data/.rubocop.yml +20 -0
- data/Gemfile +12 -3
- data/Makefile +3 -0
- data/README.md +36 -2
- data/Rakefile +8 -6
- data/active_form_model.gemspec +18 -16
- data/bin/console +4 -3
- data/lib/active_form_model/permittable.rb +56 -0
- data/lib/active_form_model/version.rb +3 -1
- data/lib/active_form_model/virtual.rb +17 -0
- data/lib/active_form_model.rb +10 -38
- data/lib/generators/active_form_model/form_generator.rb +1 -1
- data/lib/generators/active_form_model/templates/{form.rb → form.erb} +0 -0
- metadata +11 -8
- data/.travis.yml +0 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3fa5b1a5d67328998e1001805d4ff580315861877e7d6bd423de7dc280fa80a9
|
|
4
|
+
data.tar.gz: 95779536fb96ffa77cf4bf984c58ab992fedb5dfa1e5c8fa5eef6455f076ffd1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2c192c1f9f633ebb23ff7a0e16c4186f251e31063103124f11d2a51b73783077c0336478686f38b517d6ac67a522ce4eac9e72cf9c68d27019659d08363f9353
|
|
7
|
+
data.tar.gz: eb21b19c8e05a3409699d3f56d8bce70d84e3d2b0f27ea1ec1fa7cd7dc9f1aed4d39e8fcaf81a444f9ccc37a3131bacb20322a7eaaa544d9262308299d38368c
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: main
|
|
2
|
+
on: [push, pull_request]
|
|
3
|
+
jobs:
|
|
4
|
+
test:
|
|
5
|
+
strategy:
|
|
6
|
+
fail-fast: true
|
|
7
|
+
matrix:
|
|
8
|
+
os: [ubuntu-latest, macos-latest]
|
|
9
|
+
# Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0'
|
|
10
|
+
ruby: [2.7, '3.0', head]
|
|
11
|
+
runs-on: ${{ matrix.os }}
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v2
|
|
14
|
+
- uses: ruby/setup-ruby@v1
|
|
15
|
+
with:
|
|
16
|
+
ruby-version: ${{ matrix.ruby }}
|
|
17
|
+
bundler-cache: true
|
|
18
|
+
- name: run test
|
|
19
|
+
run: make test
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# The behavior of RuboCop can be controlled via the .rubocop.yml
|
|
2
|
+
# configuration file. It makes it possible to enable/disable
|
|
3
|
+
# certain cops (checks) and to alter their behavior if they accept
|
|
4
|
+
# any parameters. The file can be placed either in your home
|
|
5
|
+
# directory or in some project directory.
|
|
6
|
+
#
|
|
7
|
+
# RuboCop will start looking for the configuration file in the directory
|
|
8
|
+
# where the inspected file is and continue its way up to the root directory.
|
|
9
|
+
#
|
|
10
|
+
# See https://docs.rubocop.org/rubocop/configuration
|
|
11
|
+
require:
|
|
12
|
+
- rubocop-minitest
|
|
13
|
+
- rubocop-rake
|
|
14
|
+
|
|
15
|
+
AllCops:
|
|
16
|
+
NewCops: enable
|
|
17
|
+
TargetRubyVersion: 2.7
|
|
18
|
+
|
|
19
|
+
Style/Documentation:
|
|
20
|
+
Enabled: false
|
data/Gemfile
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source 'https://rubygems.org'
|
|
2
4
|
|
|
3
5
|
# Specify your gem's dependencies in active_form_model.gemspec
|
|
4
6
|
gemspec
|
|
5
7
|
|
|
6
|
-
gem
|
|
7
|
-
|
|
8
|
+
gem 'minitest'
|
|
9
|
+
|
|
10
|
+
gem 'rake'
|
|
11
|
+
|
|
12
|
+
gem 'rubocop'
|
|
13
|
+
|
|
14
|
+
gem 'minitest-power_assert'
|
|
15
|
+
gem 'rubocop-minitest'
|
|
16
|
+
gem 'rubocop-rake'
|
data/Makefile
CHANGED
data/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# ActiveFormModel
|
|
2
2
|
|
|
3
|
+
[](https://actions-badge.atrox.dev/hexlet/hexlet-cv/goto)
|
|
4
|
+
|
|
3
5
|
Painless forms for ActiveRecord. Based on Inheritance. Included:
|
|
4
6
|
|
|
5
7
|
* Strong parameters
|
|
@@ -47,7 +49,7 @@ class UserSignUpForm < User
|
|
|
47
49
|
include ActiveFormModel
|
|
48
50
|
|
|
49
51
|
# list all the permitted params
|
|
50
|
-
|
|
52
|
+
fields :first_name, :email, :password
|
|
51
53
|
|
|
52
54
|
# add validation if necessary
|
|
53
55
|
# they will be merged with base class' validation
|
|
@@ -64,13 +66,45 @@ class UserSignUpForm < User
|
|
|
64
66
|
end
|
|
65
67
|
```
|
|
66
68
|
|
|
67
|
-
In some cases it is necessary to use ActiveRecord object directly without form. For such cases conveniently to use method `
|
|
69
|
+
In some cases it is necessary to use ActiveRecord object directly without form. For such cases conveniently to use method `becomes()` (built-in ActiveRecord):
|
|
68
70
|
|
|
69
71
|
```ruby
|
|
70
72
|
user = User.find(params[:id])
|
|
71
73
|
form = user.becomes(UserSignUpForm)
|
|
72
74
|
```
|
|
73
75
|
|
|
76
|
+
If you want to build virtual form that is not tied to any class:
|
|
77
|
+
|
|
78
|
+
```ruby
|
|
79
|
+
# frozen_string_literal: true
|
|
80
|
+
|
|
81
|
+
class SignInForm
|
|
82
|
+
include ActiveFormModel::Virtual
|
|
83
|
+
|
|
84
|
+
fields :email, :password
|
|
85
|
+
|
|
86
|
+
validates :email, presence: true
|
|
87
|
+
validates :password, presence: true
|
|
88
|
+
validate :user_exists, :user_can_sign_in
|
|
89
|
+
|
|
90
|
+
def user_can_sign_in
|
|
91
|
+
errors.add(:password, :cannot_sign_in) if password.present? && !user&.valid_password?(password)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def user_exists
|
|
95
|
+
errors.add(:email, :user_does_not_exist_html) if email.present? && !user
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def user
|
|
99
|
+
@user ||= User.find_by(email: email)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def email=(value)
|
|
103
|
+
@email = value.downcase
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
```
|
|
107
|
+
|
|
74
108
|
## Development
|
|
75
109
|
|
|
76
110
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/Rakefile
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rake/testtask'
|
|
3
5
|
|
|
4
6
|
Rake::TestTask.new(:test) do |t|
|
|
5
|
-
t.libs <<
|
|
6
|
-
t.libs <<
|
|
7
|
-
t.test_files = FileList[
|
|
7
|
+
t.libs << 'test'
|
|
8
|
+
t.libs << 'lib'
|
|
9
|
+
t.test_files = FileList['test/**/*_test.rb']
|
|
8
10
|
end
|
|
9
11
|
|
|
10
|
-
task :
|
|
12
|
+
task default: :test
|
data/active_form_model.gemspec
CHANGED
|
@@ -1,34 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'lib/active_form_model/version'
|
|
2
4
|
|
|
3
5
|
Gem::Specification.new do |spec|
|
|
4
|
-
spec.name =
|
|
6
|
+
spec.name = 'active_form_model'
|
|
5
7
|
spec.version = ActiveFormModel::VERSION
|
|
6
|
-
spec.authors = [
|
|
7
|
-
spec.email = [
|
|
8
|
+
spec.authors = ['Kirill']
|
|
9
|
+
spec.email = ['mokevnin@gmail.com']
|
|
8
10
|
|
|
9
|
-
spec.summary =
|
|
10
|
-
spec.description =
|
|
11
|
-
spec.homepage =
|
|
12
|
-
spec.license =
|
|
13
|
-
spec.required_ruby_version = Gem::Requirement.new(
|
|
11
|
+
spec.summary = 'Painless forms for ActiveRecord'
|
|
12
|
+
spec.description = 'Based on inheritance'
|
|
13
|
+
spec.homepage = 'https://github.com/Hexlet/active_form_model'
|
|
14
|
+
spec.license = 'MIT'
|
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0')
|
|
14
16
|
|
|
15
17
|
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
|
16
18
|
|
|
17
|
-
spec.metadata[
|
|
18
|
-
spec.metadata[
|
|
19
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
20
|
+
spec.metadata['source_code_uri'] = 'https://github.com/Hexlet/form-model.git'
|
|
19
21
|
# spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
|
|
20
22
|
|
|
21
23
|
# Specify which files should be added to the gem when it is released.
|
|
22
24
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
23
|
-
spec.files
|
|
25
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
24
26
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
25
27
|
end
|
|
26
|
-
spec.bindir =
|
|
28
|
+
spec.bindir = 'exe'
|
|
27
29
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
28
|
-
spec.require_paths = [
|
|
30
|
+
spec.require_paths = ['lib']
|
|
29
31
|
|
|
30
|
-
spec.add_dependency(
|
|
32
|
+
spec.add_dependency('activesupport', '>= 3')
|
|
31
33
|
|
|
32
|
-
spec.add_development_dependency(
|
|
33
|
-
spec.add_development_dependency(
|
|
34
|
+
spec.add_development_dependency('actionpack', '>= 5')
|
|
35
|
+
spec.add_development_dependency('activemodel', '>= 5')
|
|
34
36
|
end
|
data/bin/console
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'active_form_model'
|
|
5
6
|
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
|
@@ -10,5 +11,5 @@ require "active_form_model"
|
|
|
10
11
|
# require "pry"
|
|
11
12
|
# Pry.start
|
|
12
13
|
|
|
13
|
-
require
|
|
14
|
+
require 'irb'
|
|
14
15
|
IRB.start(__FILE__)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/deprecation/reporting'
|
|
4
|
+
|
|
5
|
+
module ActiveFormModel
|
|
6
|
+
module Permittable
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
prepend Prepended
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module Prepended
|
|
14
|
+
def initialize(attrs = {})
|
|
15
|
+
permitted_attrs = permit_attrs(attrs)
|
|
16
|
+
super(permitted_attrs)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class_methods do
|
|
21
|
+
def fields(*args)
|
|
22
|
+
@_permitted_args = args
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def permit(*args)
|
|
26
|
+
ActiveSupport::Deprecation.warn('permit is deprecated in favor of fields')
|
|
27
|
+
@_permitted_args = args
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def _permitted_args
|
|
31
|
+
@_permitted_args || (superclass.respond_to?(:_permitted_args) && superclass._permitted_args) || []
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def update(attrs = {})
|
|
36
|
+
permitted_attrs = permit_attrs(attrs)
|
|
37
|
+
super(permitted_attrs)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def update!(attrs = {})
|
|
41
|
+
permitted_attrs = permit_attrs(attrs)
|
|
42
|
+
super(permitted_attrs)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def assign_attributes(attrs = {})
|
|
46
|
+
permitted_attrs = permit_attrs(attrs)
|
|
47
|
+
super(permitted_attrs)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def permit_attrs(attrs)
|
|
53
|
+
attrs.respond_to?(:permit) ? attrs.send(:permit, self.class._permitted_args) : attrs
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveFormModel
|
|
4
|
+
module Virtual
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
include Permittable
|
|
8
|
+
include ActiveModel::Model
|
|
9
|
+
|
|
10
|
+
class_methods do
|
|
11
|
+
def fields(*attrs)
|
|
12
|
+
send(:attr_accessor, *attrs)
|
|
13
|
+
super(attrs)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/active_form_model.rb
CHANGED
|
@@ -1,52 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'active_form_model/version'
|
|
2
4
|
require 'active_support/concern'
|
|
3
5
|
|
|
4
6
|
module ActiveFormModel
|
|
7
|
+
autoload :Virtual, 'active_form_model/virtual'
|
|
8
|
+
autoload :Permittable, 'active_form_model/permittable'
|
|
9
|
+
|
|
5
10
|
class Error < StandardError; end
|
|
6
11
|
|
|
7
12
|
extend ActiveSupport::Concern
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
prepend Included
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
module Included
|
|
14
|
-
def initialize(attrs = {})
|
|
15
|
-
permitted_attrs = permit_attrs(attrs)
|
|
16
|
-
super(permitted_attrs)
|
|
17
|
-
end
|
|
18
|
-
end
|
|
14
|
+
include Permittable
|
|
19
15
|
|
|
20
|
-
|
|
16
|
+
class_methods do
|
|
21
17
|
delegate :sti_name, to: :superclass
|
|
22
18
|
delegate :human_attribute_name, to: :superclass
|
|
23
|
-
# delegate :name, to: :superclass
|
|
24
|
-
|
|
25
|
-
def permit(*args)
|
|
26
|
-
@_permitted_args = args
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def _permitted_args
|
|
30
|
-
@_permitted_args || (superclass.respond_to?(:_permitted_args) && superclass._permitted_args) || []
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def update(attrs = {})
|
|
35
|
-
permitted_attrs = permit_attrs(attrs)
|
|
36
|
-
super(permitted_attrs)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def update!(attrs = {})
|
|
40
|
-
permitted_attrs = permit_attrs(attrs)
|
|
41
|
-
super(permitted_attrs)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def assign_attributes(attrs = {})
|
|
45
|
-
permitted_attrs = permit_attrs(attrs)
|
|
46
|
-
super(permitted_attrs)
|
|
47
|
-
end
|
|
48
19
|
|
|
49
|
-
|
|
50
|
-
|
|
20
|
+
# NOTE: too many side effects if it is enabled
|
|
21
|
+
# examples: form names, translations
|
|
22
|
+
# delegate :name, to: :superclass
|
|
51
23
|
end
|
|
52
24
|
end
|
|
@@ -7,7 +7,7 @@ module ActiveFormModel
|
|
|
7
7
|
source_root File.expand_path('templates', __dir__)
|
|
8
8
|
|
|
9
9
|
def create_form
|
|
10
|
-
template 'form.rb', File.join('app/forms', class_path, "#{file_name}_form.
|
|
10
|
+
template 'form.rb', File.join('app/forms', class_path, "#{file_name}_form.erb")
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
end
|
|
File without changes
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_form_model
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kirill
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-12-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -25,7 +25,7 @@ dependencies:
|
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '3'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: actionpack
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - ">="
|
|
@@ -39,7 +39,7 @@ dependencies:
|
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '5'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
42
|
+
name: activemodel
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - ">="
|
|
@@ -59,8 +59,9 @@ executables: []
|
|
|
59
59
|
extensions: []
|
|
60
60
|
extra_rdoc_files: []
|
|
61
61
|
files:
|
|
62
|
+
- ".github/workflows/main.yml"
|
|
62
63
|
- ".gitignore"
|
|
63
|
-
- ".
|
|
64
|
+
- ".rubocop.yml"
|
|
64
65
|
- CODE_OF_CONDUCT.md
|
|
65
66
|
- Gemfile
|
|
66
67
|
- LICENSE.txt
|
|
@@ -71,10 +72,12 @@ files:
|
|
|
71
72
|
- bin/console
|
|
72
73
|
- bin/setup
|
|
73
74
|
- lib/active_form_model.rb
|
|
75
|
+
- lib/active_form_model/permittable.rb
|
|
74
76
|
- lib/active_form_model/version.rb
|
|
77
|
+
- lib/active_form_model/virtual.rb
|
|
75
78
|
- lib/generators/active_form_model/USAGE
|
|
76
79
|
- lib/generators/active_form_model/form_generator.rb
|
|
77
|
-
- lib/generators/active_form_model/templates/form.
|
|
80
|
+
- lib/generators/active_form_model/templates/form.erb
|
|
78
81
|
homepage: https://github.com/Hexlet/active_form_model
|
|
79
82
|
licenses:
|
|
80
83
|
- MIT
|
|
@@ -89,14 +92,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
89
92
|
requirements:
|
|
90
93
|
- - ">="
|
|
91
94
|
- !ruby/object:Gem::Version
|
|
92
|
-
version: 2.
|
|
95
|
+
version: 2.7.0
|
|
93
96
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
97
|
requirements:
|
|
95
98
|
- - ">="
|
|
96
99
|
- !ruby/object:Gem::Version
|
|
97
100
|
version: '0'
|
|
98
101
|
requirements: []
|
|
99
|
-
rubygems_version: 3.
|
|
102
|
+
rubygems_version: 3.2.32
|
|
100
103
|
signing_key:
|
|
101
104
|
specification_version: 4
|
|
102
105
|
summary: Painless forms for ActiveRecord
|