rails_application_service 0.3.0 → 0.5.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: 9c641e4fbbd7285a049ad2591e7a2b3718454d16d6a073c25a300b4c710a1488
4
- data.tar.gz: eb5ebadd1db4a2c99f87f4412e26fb4c0d7e2bef4591e08a3254fd1ad139c9ab
3
+ metadata.gz: 1ce7c95dcdb2c3e8a3155219906c39a736ec5a5cb820e819d9f82291f09465fd
4
+ data.tar.gz: 4a6f8d3dbd8af987d39922c8b9fcd3d55363c8037576349ec35c909ed56d7b87
5
5
  SHA512:
6
- metadata.gz: e809c189672e0e993fa9e57426f792056d6911a3c7dcd2141f584dd7987c9292d70f135d1ce1de1668d330b474c728a502ceb22046a57536c1c375695a1a2b78
7
- data.tar.gz: b7a2964668a29e95b7d3482c0f2f9756f211af8e7d8bd1c8877f90ac32c6332801ef6c8c8c793dbe9aabfe389c41f66e898c04f5cb03e20af602d26da5f8c934
6
+ metadata.gz: 6396cdf5260b37a651d9d09a06e9e37f8f4fb5a54d16f8de44ed055550910abfcbb369c3fdd97901e25c7b55154744715ed47721f9ab73d3534f5fa7c170e7ee
7
+ data.tar.gz: 37118f9adfcc779cbd17f50af24505921a0098ce2c5a95e2361694eb497f0fc125fabe4869b8d7892bfa6246126b9043a0c82fcac04a788471a768c7597ddbb3
data/.rubocop.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  AllCops:
2
2
  NewCops: enable
3
- TargetRubyVersion: 2.0
3
+ TargetRubyVersion: 2.2
4
4
  SuggestExtensions: false
5
5
 
6
6
  Style/StringLiterals:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,89 @@
1
- ## [Unreleased]
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](http://keepachangelog.com/)
6
+ and this project adheres to [Semantic Versioning](http://semver.org/).
7
+
8
+ ## [Unreleased] - yyyy-mm-dd
9
+
10
+ Here we write upgrading notes for brands. It's a team effort to make them as
11
+ straightforward as possible.
12
+
13
+ ### Added
14
+ - [PROJECTNAME-XXXX](http://tickets.projectname.com/browse/PROJECTNAME-XXXX)
15
+ MINOR Ticket title goes here.
16
+ - [PROJECTNAME-YYYY](http://tickets.projectname.com/browse/PROJECTNAME-YYYY)
17
+ PATCH Ticket title goes here.
18
+
19
+ ### Changed
20
+
21
+ ### Removed
22
+
23
+ ### Breaking Changes
24
+
25
+ ## [0.5.0] - 2025-06-16
26
+
27
+ ### Added
28
+
29
+ ### Changed
30
+ - Code documentation and Readme were enhanced
31
+ - Test specs were refactored and simplified
32
+ - Rubocop offenses were fixed
33
+ - Dependencies were updated
34
+
35
+ ### Removed
36
+
37
+ ### Breaking Changes
38
+
39
+ ## [0.4.0] - 2025-06-16
40
+
41
+ ### Added
42
+ - Support for `ActiveModel::API` and `ActiveModel::Attributes` was added
43
+ - Type casting through `ActiveModel::Attributes` was added
44
+ - Validation through `ActiveModel::Validations` was added
45
+
46
+ ### Changed
47
+ - Service initialization now uses keyword arguments exclusively
48
+ - Improved error messages and documentation
49
+ - Enhanced example code in docstrings
50
+
51
+ ### Removed
52
+ - Support for positional arguments in the `call` method
53
+
54
+ ### Breaking Changes
55
+ - Services must now use keyword arguments instead of positional arguments
56
+ - All existing services using positional arguments need to be updated
57
+
58
+ ## [0.3.0] - 2025-02-05
59
+
60
+ ### Added
61
+
62
+ ### Changed
63
+ - Source code and tests were refactored
64
+
65
+ ### Removed
66
+
67
+ ### Breaking Changes
68
+
69
+ ## [0.2.0] - 2025-02-04
70
+
71
+ ### Added
72
+
73
+ ### Changed
74
+ - Source code and tests were refactored
75
+
76
+ ### Removed
77
+
78
+ ### Breaking Changes
2
79
 
3
80
  ## [0.1.0] - 2025-02-04
4
81
 
82
+ ### Added
5
83
  - Initial release
84
+
85
+ ### Changed
86
+
87
+ ### Removed
88
+
89
+ ### Breaking Changes
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # ApplicationService
1
+ # Rails Application Service
2
2
 
3
3
  Service objects for Rails - the Rails way. This Ruby gem adds service objects to Rails applications.
4
4
 
@@ -6,8 +6,8 @@ Service objects for Rails - the Rails way. This Ruby gem adds service objects to
6
6
 
7
7
  **1 - Add the gem to the Rails application's Gemfile by entering:**
8
8
 
9
- ```yaml
10
- gem "application_service", git: "https://github.com/mariomarroquim/rails_application_service"
9
+ ```bash
10
+ bundle add rails_application_service
11
11
  ```
12
12
 
13
13
  **2 - Install the gem into the Rails application's directory by running:**
@@ -16,19 +16,19 @@ gem "application_service", git: "https://github.com/mariomarroquim/rails_applica
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` subdirectory in the Rails application's directory by running:**
20
20
  ```bash
21
21
  mkdir -p app/services
22
22
  ```
23
23
 
24
24
  ## Usage
25
25
 
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.
26
+ 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.
27
27
 
28
28
  ### Example of a basic service:
29
-
30
- Create an `app/services` subdirectory into the Rails application's one with your service by running:
31
29
  ```ruby
30
+ require "application_service"
31
+
32
32
  class MyService < ApplicationService::Base
33
33
  def call
34
34
  # Perform the service action
@@ -38,28 +38,37 @@ end
38
38
  my_service = MyService.call # nil
39
39
  ```
40
40
 
41
- ### Example of a more complete service:
41
+ ### Example of a service:
42
42
  ```ruby
43
- class Sum < ApplicationService::Base
44
- attr_accessor :number_a, :number_b
45
-
46
- validates :number_a, :number_b, presence: true, numericality: { only_integer: true, greater_than: 0 }
43
+ require "application_service"
47
44
 
48
- def initialize(number_a, number_b)
49
- super
45
+ class Sum < ApplicationService::Base
46
+ attribute :number_a, :integer
47
+ attribute :number_b, :integer
50
48
 
51
- self.number_a = number_a
52
- self.number_b = number_b
53
- end
49
+ validates :number_a, :number_b, presence: true, numericality: { greater_than: 0 }
54
50
 
55
51
  def call
56
- (number_a + number_b)
52
+ number_a + number_b
57
53
  end
58
54
  end
59
55
 
60
- sum = Sum.call(1, 2) # 2
56
+ sum = Sum.call(number_a: 1, number_b: 2) # => 3
61
57
  ```
62
58
 
59
+ ### Available attribute types
60
+
61
+ This gem supports the following attribute types through `ActiveModel::Attributes` and other custom types defined in `ActiveModel::Type`:
62
+
63
+ - `:boolean`
64
+ - `:date`
65
+ - `:datetime`
66
+ - `:decimal`
67
+ - `:float`
68
+ - `:integer`
69
+ - `:string`
70
+ - `:time`
71
+
63
72
  ## Development
64
73
 
65
74
  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.
@@ -76,7 +85,7 @@ The gem is available as open source under the terms of the [MIT License](https:/
76
85
 
77
86
  ## Code of Conduct
78
87
 
79
- 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).
88
+ 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).
80
89
 
81
90
  ## Support
82
91
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ApplicationService
4
- VERSION = "0.3.0"
4
+ VERSION = "0.5.0"
5
5
  end
@@ -8,51 +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
+ return unless instance_of?(Base)
55
+
56
+ raise ::NotImplementedError, "#{self.class.name} is an abstract class and cannot be instantiated directly"
48
57
  end
49
58
 
50
59
  # Initializes a new instance of the 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)
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)
56
66
 
57
67
  return false unless service.valid?
58
68
 
@@ -63,7 +73,7 @@ module ApplicationService
63
73
  #
64
74
  # @raise [NotImplementedError] if the method is not implemented in a child class
65
75
  def call
66
- raise NotImplementedError, "The `call` method must be implemented in #{self.class}"
76
+ raise ::NotImplementedError, "The `call` method must be implemented in #{self.class.name}"
67
77
  end
68
78
  end
69
79
  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.3.0
4
+ version: 0.5.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
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 4.2.5
18
+ version: '4.2'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: 4.2.5
25
+ version: '4.2'
26
26
  description: This Ruby gem adds service objects to Rails applications.
27
27
  email:
28
28
  - mariomarroquim@gmail.com
@@ -55,14 +55,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
55
55
  requirements:
56
56
  - - ">="
57
57
  - !ruby/object:Gem::Version
58
- version: '2.0'
58
+ version: '2.2'
59
59
  required_rubygems_version: !ruby/object:Gem::Requirement
60
60
  requirements:
61
61
  - - ">="
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: []