rails_application_service 0.4.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f2660a3497bae6216e343a1b8a930f75bbd0dd470ed3229060cc8881438d56b1
4
- data.tar.gz: b97c1a7919d2ca70aef177a1701e14416caf3f0a170970bbecfcf10c0e745a49
3
+ metadata.gz: b7e3b78a33f41ea84a56ce29d482a739d1c4431122ec8eb766d76fd4d4598552
4
+ data.tar.gz: 5cf617de77f52dad4444d4cdfefbfd84b62e1bf2d54a3e0140dd64d890ab5661
5
5
  SHA512:
6
- metadata.gz: 5ab05ae5a159d838c65ff1b41badb518df968734462c9d52eaeeed705643de2ca6cf1aec0bc529d0f4d045efc98d4c612ebec5a7f351a953f8205fa9571cce2f
7
- data.tar.gz: ef48067c66734b18053e04c6bc87934b9841fc4adcd19e39fe7e526d032d4f64506553c7020d7ffff5b416664e2a517b1d964f4e8dc9bc4fd3360abab5e43e1e
6
+ metadata.gz: 6116887b8a93ab25f5efcea6ab0e03c3f9cffd75aa7be4df4437956979db258b9d9ac671fa43323ebf26b2e78a5b3787c36ea888c41d07063d46e2c0d99e8948
7
+ data.tar.gz: cf929d8a4dad1d3f330a35b65cf1506aa67d0c0ab18c3113b9bab6a1451593c1862f74c321bf0a6fac15dd24fdee79073dfbb7f2b9400971c581a13743f7d561
data/CHANGELOG.md CHANGED
@@ -1,5 +1,83 @@
1
- ## [Unreleased]
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.6.0] - 2025-06-16
9
+
10
+ ### Added
11
+
12
+ ### Changed
13
+ - Enhanced the changelog
14
+
15
+ ### Removed
16
+
17
+ ### Breaking Changes
18
+
19
+ ## [0.5.0] - 2025-06-16
20
+
21
+ ### Added
22
+
23
+ ### Changed
24
+ - Improved code documentation and README
25
+ - Refactored and simplified test specs
26
+ - Fixed Rubocop offenses
27
+ - Updated dependencies
28
+
29
+ ### Removed
30
+
31
+ ### Breaking Changes
32
+
33
+ ## [0.4.0] - 2025-06-16
34
+
35
+ ### Added
36
+ - Added support for `ActiveModel::API` and `ActiveModel::Attributes`
37
+ - Enabled type casting through `ActiveModel::Attributes`
38
+ - Added validation via `ActiveModel::Validations`
39
+
40
+ ### Changed
41
+ - Service initialization now exclusively uses keyword arguments
42
+ - Improved error messages and documentation
43
+ - Enhanced example code in docstrings
44
+
45
+ ### Removed
46
+ - Removed support for positional arguments in the `call` method
47
+
48
+ ### Breaking Changes
49
+ - Services must now use keyword arguments instead of positional arguments
50
+ - All existing services using positional arguments need to be updated
51
+
52
+ ## [0.3.0] - 2025-02-05
53
+
54
+ ### Added
55
+
56
+ ### Changed
57
+ - Refactored source code and tests
58
+
59
+ ### Removed
60
+
61
+ ### Breaking Changes
62
+
63
+ ## [0.2.0] - 2025-02-04
64
+
65
+ ### Added
66
+
67
+ ### Changed
68
+ - Refactored source code and tests
69
+
70
+ ### Removed
71
+
72
+ ### Breaking Changes
2
73
 
3
74
  ## [0.1.0] - 2025-02-04
4
75
 
76
+ ### Added
5
77
  - Initial release
78
+
79
+ ### Changed
80
+
81
+ ### Removed
82
+
83
+ ### Breaking Changes
data/README.md CHANGED
@@ -1,32 +1,36 @@
1
- # ApplicationService
1
+ # Rails Application Service
2
2
 
3
- Service objects for Rails - the Rails way. This Ruby gem adds service objects to Rails applications.
3
+ Service objects for Rails, the Rails way. This Ruby gem adds service objects to your Rails applications.
4
4
 
5
5
  ## Installation
6
6
 
7
- **1 - Add the gem to the Rails application's Gemfile by entering:**
7
+ **1 - Add the gem to your Rails application's Gemfile:**
8
8
 
9
9
  ```bash
10
- gem add application_service
10
+ bundle add rails_application_service
11
11
  ```
12
12
 
13
- **2 - Install the gem into the Rails application's directory by running:**
13
+ **2 - Install the gem by running:**
14
14
 
15
15
  ```bash
16
16
  bundle install
17
17
  ```
18
18
 
19
- **3 - Create a `app/services` subdirectory into the Rails application's directory by running:**
19
+ **3 - Create an `app/services` directory in your Rails application:**
20
+
20
21
  ```bash
21
22
  mkdir -p app/services
22
23
  ```
23
24
 
24
25
  ## Usage
25
26
 
26
- The `ApplicationService::Base` class provides a standard interface for calling service objects. It defines a class method `call` that initializes a new instance of the service object and invokes its `call` instance method. The `call` method can accept any number of arguments, which are passed to the initializer of the service object. You can define attributes and validations just like in Active Record, using the same syntax and conventions.
27
+ The `ApplicationService::Base` class provides a standard interface for calling service objects with robust type handling and validations. It leverages `ActiveModel::API` for initialization with keyword arguments, `ActiveModel::Attributes` for type casting, and `ActiveModel::Validations` for input validation.
28
+
29
+ ### Basic service example
27
30
 
28
- ### Example of a basic service:
29
31
  ```ruby
32
+ require "application_service"
33
+
30
34
  class MyService < ApplicationService::Base
31
35
  def call
32
36
  # Perform the service action
@@ -36,33 +40,43 @@ end
36
40
  my_service = MyService.call # nil
37
41
  ```
38
42
 
39
- ### Example of a more complete service:
40
- ```ruby
41
- class Sum < ApplicationService::Base
42
- attr_accessor :number_a, :number_b
43
+ ### Example with attributes and validations
43
44
 
44
- validates :number_a, :number_b, presence: true, numericality: { only_integer: true, greater_than: 0 }
45
+ ```ruby
46
+ require "application_service"
45
47
 
46
- def initialize(number_a, number_b)
47
- super
48
+ class Sum < ApplicationService::Base
49
+ attribute :number_a, :integer
50
+ attribute :number_b, :integer
48
51
 
49
- self.number_a = number_a
50
- self.number_b = number_b
51
- end
52
+ validates :number_a, :number_b, presence: true, numericality: { greater_than: 0 }
52
53
 
53
54
  def call
54
- (number_a + number_b)
55
+ number_a + number_b
55
56
  end
56
57
  end
57
58
 
58
- sum = Sum.call(1, 2) # 2
59
+ sum = Sum.call(number_a: 1, number_b: 2) # => 3
59
60
  ```
60
61
 
62
+ ### Supported attribute types
63
+
64
+ This gem supports the following attribute types through `ActiveModel::Attributes` and custom types defined in `ActiveModel::Type`:
65
+
66
+ - `:boolean`
67
+ - `:date`
68
+ - `:datetime`
69
+ - `:decimal`
70
+ - `:float`
71
+ - `:integer`
72
+ - `:string`
73
+ - `:time`
74
+
61
75
  ## Development
62
76
 
63
- 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.
77
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to execute the tests. You can also run `bin/console` for an interactive prompt to experiment.
64
78
 
65
- 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 the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
79
+ 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`, then run `bundle exec rake release`. This will create a git tag for the version, push git commits and the tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
66
80
 
67
81
  ## Contributing
68
82
 
@@ -74,7 +88,7 @@ The gem is available as open source under the terms of the [MIT License](https:/
74
88
 
75
89
  ## Code of Conduct
76
90
 
77
- Everyone interacting in the ApplicationService project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/mariomarroquim/rails_application_service/blob/main/CODE_OF_CONDUCT.md).
91
+ Everyone interacting in the ApplicationService project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the [code of conduct](https://github.com/mariomarroquim/rails_application_service/blob/main/CODE_OF_CONDUCT.md).
78
92
 
79
93
  ## Support
80
94
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ApplicationService
4
- VERSION = "0.4.0"
4
+ VERSION = "0.6.0"
5
5
  end
@@ -8,52 +8,61 @@ require "active_model"
8
8
  # perform a single action or a series of related actions.
9
9
  module ApplicationService
10
10
  # The Base class within the ApplicationService module provides a standard
11
- # interface for calling service objects. It defines a class method `call`
12
- # that initializes a new instance of the service object and invokes its
13
- # `call` instance method.
11
+ # interface for calling service objects with robust type handling and validations.
12
+ # It leverages ActiveModel::API for initialization with keyword arguments,
13
+ # ActiveModel::Attributes for type casting, and ActiveModel::Validations for
14
+ # input validation.
14
15
  #
15
16
  # Example usage:
16
- # class Sum < ApplicationService::Base
17
- # attr_accessor :number_a, :number_b
18
- #
19
- # validates :number_a, :number_b, presence: true, numericality: { only_integer: true, greater_than: 0 }
20
17
  #
21
- # def initialize(number_a, number_b)
22
- # super
18
+ # class Sum < ApplicationService::Base
19
+ # attribute :number_a, :integer
20
+ # attribute :number_b, :integer
23
21
  #
24
- # self.number_a = number_a
25
- # self.number_b = number_b
26
- # end
22
+ # validates :number_a, :number_b, presence: true, numericality: { greater_than: 0 }
27
23
  #
28
24
  # def call
29
- # (number_a + number_b)
25
+ # number_a + number_b
30
26
  # end
31
27
  # end
32
28
  #
33
- # sum = Sum.call(1, 2) # 2
29
+ # sum = Sum.call(number_a: 1, number_b: 2) # => 3
34
30
  #
35
- # The `call` method can accept any number of arguments, which are
36
- # passed to the initializer of the service object. You can define
37
- # attributes and validations just like in Active Record, using
38
- # the same syntax and conventions.
31
+ # This gem supports the following attribute types through ActiveModel::Attributes and
32
+ # other custom types defined in ActiveModel::Type:
33
+ #
34
+ # - :boolean
35
+ # - :date
36
+ # - :datetime
37
+ # - :decimal
38
+ # - :float
39
+ # - :integer
40
+ # - :string
41
+ # - :time
39
42
  class Base
43
+ include ::ActiveModel::API
44
+ include ::ActiveModel::Attributes
40
45
  include ::ActiveModel::Validations
41
46
 
42
47
  # Initializes a new instance of the service object.
43
48
  #
44
- # @param args [Array] the arguments to be passed to the initializer of the service object
45
- # @raise [NotImplementedError] if an attempt is made to instantiate the abstract class directly
46
- def initialize(*_args)
47
- raise NotImplementedError, "#{self.class} can not be instantiated" if instance_of?(Base)
49
+ # @param kwargs [Hash] The attributes to be passed to the service object.
50
+ # @raise [NotImplementedError] if an attempt is made to instantiate the Base class directly.
51
+ def initialize(**kwargs)
52
+ super
53
+
54
+ if instance_of?(Base)
55
+ raise ::NotImplementedError, "#{self.class.name} is an abstract class and cannot be instantiated directly"
56
+ end
48
57
  end
49
58
 
50
- # Initializes a new instance of the service object and invokes its `call` method.
59
+ # Instantiates a new service object and invokes its `call` method.
51
60
  #
52
- # @param args [Array] the arguments to be passed to the initializer of the service object
53
- # @return [Object] the recently instantiated service object
54
- def self.call(*args)
55
- service = new(*args)
56
-
61
+ # @param kwargs [Hash] The attributes to be passed to the service object.
62
+ # @return [Object] The result of the service object's call method.
63
+ # @return [false] If the service object is invalid.
64
+ def self.call(**kwargs)
65
+ service = new(**kwargs)
57
66
  return false unless service.valid?
58
67
 
59
68
  service.call
@@ -61,9 +70,9 @@ module ApplicationService
61
70
 
62
71
  # Encapsulates the implementation to be executed by the service object.
63
72
  #
64
- # @raise [NotImplementedError] if the method is not implemented in a child class
73
+ # @raise [NotImplementedError] if the method is not implemented in a child class.
65
74
  def call
66
- raise NotImplementedError, "The `call` method must be implemented in #{self.class}"
75
+ raise ::NotImplementedError, "The `call` method must be implemented in #{self.class.name}"
67
76
  end
68
77
  end
69
78
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_application_service
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mário Marroquim
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-02-05 00:00:00.000000000 Z
10
+ date: 2025-06-18 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: activemodel
@@ -62,7 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
62
62
  - !ruby/object:Gem::Version
63
63
  version: '0'
64
64
  requirements: []
65
- rubygems_version: 3.6.3
65
+ rubygems_version: 3.6.6
66
66
  specification_version: 4
67
67
  summary: Service objects for Rails - the Rails way.
68
68
  test_files: []