granite 0.15.0 → 0.15.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2cf5813f23b963898bbdd4f55d35b2f0699428c657413ee6f18d56713ffcf659
4
- data.tar.gz: 48a04a7a60bf1819222728acf33c8bf0a73149d9b9d83b2ea04bc70a2182ec04
3
+ metadata.gz: d0a4953c8a4a24dfab614a8831bb8b39cda81d4a0b2d7e3ea8f2bb5d3d8eccc4
4
+ data.tar.gz: 6f1655c4167aef595d7c36fcd0fbde9e72376bd1fec2dafc38e6dc508f4f0417
5
5
  SHA512:
6
- metadata.gz: b182f94aa37d25756606fe9384a5ea98963279f8a58f84a66a7660fd21a3076b46f6965d56e26d5bc75357431f9bec2dfabb639bd198b0d00529d2567dd21628
7
- data.tar.gz: 814dbec1866a2845d869489d82051feb017e4c850460fef1af69f13d31cf6c40fb66dbddec52529e84dfd292acce8bf73bb4479f9f8e2fca42c586c9dd12b2a2
6
+ metadata.gz: bd0b0f97527283426bdaf8f5d25cf033053f0636958578621c84f5c8fc0c01f70528f1d759213ac0cddbc3327d5b06951b231d18cce3e987c612697dabb90c89
7
+ data.tar.gz: deff30290527973e4dee79d4584c7ffd5090a80737da57d1efe48e8fcdd89d0e11d220c8b5c81b55f313f2d3ced81b097ab454c67065b6db458629e18924c236
@@ -5,11 +5,11 @@ class GraniteGenerator < Rails::Generators::NamedBase
5
5
  class_option :collection, type: :boolean, aliases: '-C', desc: 'Generate collection action'
6
6
 
7
7
  def create_action
8
- template 'granite_action.rb.erb', "apq/actions/ba/#{file_path}.rb"
9
- template 'granite_business_action.rb.erb', "apq/actions/ba/#{class_path.join('/')}/business_action.rb" unless options.collection?
8
+ template 'granite_action.rb.erb', "apq/actions/#{file_path}.rb"
9
+ template 'granite_business_action.rb.erb', "apq/actions/#{class_path.join('/')}/business_action.rb" unless options.collection?
10
10
  template 'granite_base_action.rb.erb', 'apq/actions/base_action.rb', skip: true
11
- template 'granite_action_spec.rb.erb', "spec/apq/actions/ba/#{file_path}_spec.rb"
12
- empty_directory "apq/actions/ba/#{file_path}/#{projector}" if projector
11
+ template 'granite_action_spec.rb.erb', "spec/apq/actions/#{file_path}_spec.rb"
12
+ empty_directory "apq/actions/#{file_path}/#{projector}" if projector
13
13
  end
14
14
 
15
15
  private
@@ -18,7 +18,7 @@ class GraniteGenerator < Rails::Generators::NamedBase
18
18
  if options.collection?
19
19
  'BaseAction'
20
20
  else
21
- "BA::#{class_path.join('/').camelize}::BusinessAction"
21
+ "#{class_path.join('/').camelize}::BusinessAction"
22
22
  end
23
23
  end
24
24
 
@@ -1,4 +1,4 @@
1
- class BA::<%= class_name %> < <%= base_class_name %>
1
+ class <%= class_name %> < <%= base_class_name %>
2
2
  <% if projector -%>
3
3
  projector :<%= projector %>
4
4
 
@@ -1,6 +1,6 @@
1
1
  require 'rails_helper'
2
2
 
3
- RSpec.describe BA::<%= class_name %> do
3
+ RSpec.describe <%= class_name %> do
4
4
  <% if options.collection? -%>
5
5
  subject(:action) { described_class.as(performer).new(attributes) }
6
6
 
@@ -1,3 +1,3 @@
1
- class BA::<%= class_path.join('/').camelize %>::BusinessAction < BaseAction
1
+ class <%= class_path.join('/').camelize %>::BusinessAction < BaseAction
2
2
  subject :<%= subject_name %>
3
3
  end
@@ -93,7 +93,6 @@ module Granite
93
93
 
94
94
  def perform_action(raise_errors: false, **options)
95
95
  result = run_callbacks(:execute_perform) do
96
- apply_association_changes!
97
96
  execute_perform!(**options)
98
97
  end
99
98
  @_action_performed = true
@@ -2,10 +2,18 @@ module Granite
2
2
  class Action
3
3
  module Types
4
4
  class Collection
5
- attr_reader :subtype
5
+ attr_reader :subtype_definition
6
6
 
7
- def initialize(subtype)
8
- @subtype = subtype
7
+ def initialize(subtype_definition)
8
+ @subtype_definition = subtype_definition
9
+ end
10
+
11
+ def ensure_type(value)
12
+ if value.respond_to? :transform_values
13
+ value.transform_values { |v| subtype_definition.ensure_type(v) }
14
+ elsif value.respond_to?(:map)
15
+ value.map { |v| subtype_definition.ensure_type(v) }
16
+ end
9
17
  end
10
18
  end
11
19
  end
data/lib/granite/base.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'granite/form/model'
2
2
  require 'granite/form/model/primary'
3
- require 'granite/form/model/lifecycle'
4
3
  require 'granite/form/model/associations'
5
4
 
6
5
  require 'granite/translations'
@@ -4,6 +4,11 @@ module Granite
4
4
  types = {}
5
5
  types[ActiveRecord::Enum::EnumType] = String if defined?(ActiveRecord)
6
6
  TYPES = types.freeze
7
+ GRANITE_COLLECTION_TYPES = [
8
+ Granite::Form::Model::Attributes::ReferenceMany,
9
+ Granite::Form::Model::Attributes::Collection,
10
+ Granite::Form::Model::Attributes::Dictionary
11
+ ].freeze
7
12
  delegate :writer, :reader, :reader_before_type_cast, to: :reflection
8
13
 
9
14
  def initialize(*_args)
@@ -17,23 +22,12 @@ module Granite
17
22
  reference.public_send(writer, read) if reference.respond_to?(writer)
18
23
  end
19
24
 
20
- def typecast(value)
21
- return value if value.class == type # rubocop:disable Style/ClassEqualityComparison
22
-
23
- typecaster.call(value, self) unless value.nil?
24
- end
25
-
26
- def type
27
- return reflection.options[:type] if reflection.options[:type].present?
28
-
29
- granite_form_type || type_from_type_for_attribute || super
30
- end
31
-
32
- def typecaster
33
- @typecaster ||= begin
34
- type_class = type.instance_of?(Class) ? type : type.class
35
- @typecaster = Granite::Form.typecaster(type_class.ancestors.grep(Class))
36
- end
25
+ def type_definition
26
+ @type_definition ||= if reflection.options[:type].present?
27
+ build_type_definition(reflection.options[:type])
28
+ else
29
+ granite_form_type_definition || active_record_type_definition || super
30
+ end
37
31
  end
38
32
 
39
33
  def changed?
@@ -54,7 +48,7 @@ module Granite
54
48
  return unless reference.respond_to?(reader)
55
49
 
56
50
  variable_cache(:value) do
57
- normalize(enumerize(typecast(defaultize(reference.public_send(reader)))))
51
+ normalize(enumerize(type_definition.ensure_type(defaultize(reference.public_send(reader)))))
58
52
  end
59
53
  end
60
54
 
@@ -66,31 +60,33 @@ module Granite
66
60
  end
67
61
  end
68
62
 
69
- def granite_form_type
63
+ def granite_form_type_definition
70
64
  return nil unless reference.is_a?(Granite::Form::Model)
71
65
 
72
66
  reference_attribute = reference.attribute(name)
73
67
 
74
68
  return nil if reference_attribute.nil?
75
69
 
76
- return Granite::Action::Types::Collection.new(reference_attribute.type) if [
77
- Granite::Form::Model::Attributes::ReferenceMany,
78
- Granite::Form::Model::Attributes::Collection,
79
- Granite::Form::Model::Attributes::Dictionary
80
- ].any? { |klass| reference_attribute.is_a? klass }
81
-
82
- reference_attribute.type # TODO: create `type_for_attribute` method inside of Granite::Form
70
+ type_definition = build_type_definition(reference_attribute.type)
71
+ if GRANITE_COLLECTION_TYPES.any? { |klass| reference_attribute.is_a? klass }
72
+ Granite::Action::Types::Collection.new(type_definition)
73
+ else
74
+ type_definition
75
+ end
83
76
  end
84
77
 
85
- def type_from_type_for_attribute
78
+ def active_record_type_definition
86
79
  return nil unless reference.respond_to?(:type_for_attribute)
87
80
 
88
81
  attribute_type = reference.type_for_attribute(attribute_name.to_s)
89
82
 
90
- return TYPES[attribute_type.class] if TYPES.key?(attribute_type.class)
91
- return Granite::Action::Types::Collection.new(convert_type_to_value_class(attribute_type.subtype)) if attribute_type.respond_to?(:subtype)
92
-
93
- convert_type_to_value_class(attribute_type)
83
+ if TYPES.key?(attribute_type.class)
84
+ build_type_definition(TYPES[attribute_type.class])
85
+ elsif attribute_type.respond_to?(:subtype)
86
+ Granite::Action::Types::Collection.new(convert_active_model_type_to_definition(attribute_type.subtype))
87
+ else
88
+ convert_active_model_type_to_definition(attribute_type)
89
+ end
94
90
  end
95
91
 
96
92
  def attribute_name
@@ -99,10 +95,10 @@ module Granite
99
95
  reference.class.attribute_aliases[name.to_s] || name
100
96
  end
101
97
 
102
- def convert_type_to_value_class(attribute_type)
103
- return attribute_type.value_class if attribute_type.respond_to?(:value_class)
104
-
105
- Granite::Form::Model::Associations::PersistenceAdapters::ActiveRecord::TYPES[attribute_type.type&.to_sym]
98
+ def convert_active_model_type_to_definition(attribute_type)
99
+ type = attribute_type.try(:value_class) ||
100
+ Form::Model::Associations::PersistenceAdapters::ActiveRecord::TYPES[attribute_type.type&.to_sym]
101
+ build_type_definition(type) if type
106
102
  end
107
103
  end
108
104
  end
@@ -1,3 +1,3 @@
1
1
  module Granite
2
- VERSION = '0.15.0'.freeze
2
+ VERSION = '0.15.1'.freeze
3
3
  end
data/lib/granite.rb CHANGED
@@ -25,7 +25,6 @@ require 'granite/dispatcher'
25
25
  require 'granite/action'
26
26
  require 'granite/projector'
27
27
  require 'granite/routing'
28
- require 'granite/typecasters'
29
- require 'granite/rails' if defined?(::Rails)
28
+ require 'granite/rails' if defined?(Rails)
30
29
 
31
30
  Granite::Form.base_concern = Granite::Base
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: granite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.15.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Toptal Engineering
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-22 00:00:00.000000000 Z
11
+ date: 2023-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -36,14 +36,14 @@ dependencies:
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: '0'
39
+ version: 0.3.0
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: '0'
46
+ version: 0.3.0
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: activesupport
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -120,6 +120,20 @@ dependencies:
120
120
  - - ">="
121
121
  - !ruby/object:Gem::Version
122
122
  version: '0'
123
+ - !ruby/object:Gem::Dependency
124
+ name: bump
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ type: :development
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
123
137
  - !ruby/object:Gem::Dependency
124
138
  name: capybara
125
139
  requirement: !ruby/object:Gem::Requirement
@@ -390,7 +404,6 @@ files:
390
404
  - lib/granite/rspec/raise_validation_error.rb
391
405
  - lib/granite/rspec/satisfy_preconditions.rb
392
406
  - lib/granite/translations.rb
393
- - lib/granite/typecasters.rb
394
407
  - lib/granite/util.rb
395
408
  - lib/granite/version.rb
396
409
  - lib/rubocop-granite.rb
@@ -415,7 +428,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
415
428
  - !ruby/object:Gem::Version
416
429
  version: '0'
417
430
  requirements: []
418
- rubygems_version: 3.2.33
431
+ rubygems_version: 3.3.26
419
432
  signing_key:
420
433
  specification_version: 4
421
434
  summary: Another business actions architecture for Rails apps
@@ -1,10 +0,0 @@
1
- require 'granite/form'
2
-
3
- Granite::Form.typecaster('Granite::Action::Types::Collection') do |value, attribute|
4
- typecaster = Granite::Form.typecaster(attribute.type.subtype)
5
- if value.respond_to? :transform_values
6
- value.transform_values { |v| typecaster.call(v, attribute) }
7
- elsif value.respond_to?(:map)
8
- value.map { |v| typecaster.call(v, attribute) }
9
- end
10
- end