action_schema 0.1.0 → 0.1.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: 1900a8787c395b5cfa7fce53e3feb8d049f33a08a0498c766d98c389aa1a30ca
4
- data.tar.gz: b51df6ac12c67618e34ad5deed5d4615a751b4d1cf999d0b38cdf7aa063d29ed
3
+ metadata.gz: f9c6d088972b4743ea5546ac98057b3f9135a9eb33ba9f942fe674322fe776a3
4
+ data.tar.gz: a8f82b40e0af0d3d00b64378552b807e98afcb37c4da5c65278a7a83452eeb91
5
5
  SHA512:
6
- metadata.gz: 9f5f8d04be3a8dfde7b46c06580446934e810b1f1486bfa5a73c3b586003d2fe5fbcad63507b4b33005f9bc4944e5570b141eb704fad20f5f61bfbe9603fec82
7
- data.tar.gz: 4f9936bc68703ab3a0ad4dcd7e3a217cf022a4cdf2cf5859b47097e8e5b543be6c5220c558e9eb86583357f06335bd55482d78c545033c44210f21246d477f0c
6
+ metadata.gz: e91dfd4a7a03bc8ce3edec61626cb129517b8dcb9e3aa5ca2b90de4b9e0f9b548f58563d24c4c4d537a15dbcdca3ccfcae65768820a3e87183da4944f17176a0
7
+ data.tar.gz: 263251f5f9d8ca9ba1ece0b3597bf45e2b74f9d0494df9383bb5b0bc3e91b7b90461251dd4fa8b6021bdb4e9c49be2a0d007126af5423148b25b8837dd38fe36
data/CHANGELOG.md CHANGED
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.1.1] - 2024-12-09
11
+
12
+ - **More Closures:** Support procs and lambdas anywhere a block is accepted in the DSL
13
+
10
14
  ## [0.1.0] - 2024-12-08
11
15
 
12
16
  ### Added
@@ -49,5 +53,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
49
53
  - 100% test coverage
50
54
  - Comprehensive documentation
51
55
 
52
- [Unreleased]: https://github.com/jtnegrotto/action_schema/compare/v0.1.0...HEAD
56
+ [Unreleased]: https://github.com/jtnegrotto/action_schema/compare/v0.1.1...HEAD
57
+ [0.1.1]: https://github.com/jtnegrotto/action_schema/compare/v0.1.0...v0.1.1
53
58
  [0.1.0]: https://github.com/jtnegrotto/action_schema/releases/tag/v0.1.0
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Gem Version](https://badge.fury.io/rb/action_schema.svg)](https://badge.fury.io/rb/action_schema)
2
+
1
3
  # ActionSchema
2
4
 
3
5
  ActionSchema provides a flexible, Rails-friendly approach to rendering ~and
@@ -8,7 +10,7 @@ parsing~ (coming soon) structured data in your controllers.
8
10
  **ActionSchema** is currently in early development. Its API is subject to
9
11
  significant changes. If you do choose to use it, please:
10
12
 
11
- * Lock the version in your Gemfile (e.g. `gem "action_schema", "= 0.1.0"`)
13
+ * Lock the version in your Gemfile (e.g. `gem "action_schema", "= 0.1.1"`)
12
14
  * Be prepared to update your code as the library evolves
13
15
  * Refer to the [CHANGELOG](CHANGELOG.md) for updates
14
16
  * [Report](https://github.com/jtnegrotto/action_schema/issues/new) any issues you encounter to help improve the library
@@ -18,7 +20,7 @@ significant changes. If you do choose to use it, please:
18
20
  Add the gem to your Gemfile:
19
21
 
20
22
  ```bash
21
- bundle add action_schema -v '= 0.1.0'
23
+ bundle add action_schema -v '= 0.1.1'
22
24
  ```
23
25
 
24
26
  ## Usage
@@ -33,10 +35,10 @@ The simplest way to define a schema is inline in your controller action:
33
35
  class UsersController < ApplicationController
34
36
  def index
35
37
  users = User.all
36
- render json: schema_for(users) do
38
+ render json: schema_for(users, -> {
37
39
  fields :id, :email
38
- computed(:full_name) { |user| "#{user.first_name} #{user.last_name}" }
39
- end
40
+ computed :full_name, ->(user) { "#{user.first_name} #{user.last_name}" }
41
+ })
40
42
  end
41
43
  end
42
44
  ```
@@ -203,8 +205,8 @@ less specific ones.
203
205
  #### Hooks
204
206
 
205
207
  You can define hooks to run before or after rendering. The `before_render` hook
206
- takes a block that receives the record or collection to be rendered. The
207
- `after_render` hook takes a block that receives the rendered data. Both hooks
208
+ takes a closure that receives the record or collection to be rendered. The
209
+ `after_render` hook takes a closure that receives the rendered data. Both hooks
208
210
  allow you to replace the data with a new value using the `transform` method:
209
211
 
210
212
  ```ruby
@@ -15,19 +15,25 @@ module ActionSchema
15
15
  new(*args, **kwargs, &block).render
16
16
  end
17
17
 
18
- def before_render(&block)
19
- self.before_render_hooks ||= []
20
- before_render_hooks << block
18
+ def before_render_hooks
19
+ @before_render_hooks ||= []
21
20
  end
22
21
 
23
- def after_render(&block)
24
- self.after_render_hooks ||= []
25
- after_render_hooks << block
22
+ def after_render_hooks
23
+ @after_render_hooks ||= []
24
+ end
25
+
26
+ def before_render(lambda_or_proc = nil, &block)
27
+ self.before_render_hooks << (lambda_or_proc || block)
28
+ end
29
+
30
+ def after_render(lambda_or_proc = nil, &block)
31
+ self.after_render_hooks << (lambda_or_proc || block)
26
32
  end
27
33
 
28
34
  def inherited(subclass)
29
- subclass.before_render_hooks = (before_render_hooks || []).dup
30
- subclass.after_render_hooks = (after_render_hooks || []).dup
35
+ subclass.before_render_hooks = before_render_hooks.dup
36
+ subclass.after_render_hooks = after_render_hooks.dup
31
37
  subclass.schema = schema.dup
32
38
  end
33
39
 
@@ -43,6 +49,8 @@ module ActionSchema
43
49
  ->(controller) { controller.resolve_schema(schema_definition) }
44
50
  elsif schema_definition.is_a?(Class)
45
51
  schema_definition
52
+ elsif schema_definition.is_a?(Proc)
53
+ Class.new(base_schema_class, &Dalambda[schema_definition])
46
54
  elsif block_given?
47
55
  Class.new(base_schema_class, &block)
48
56
  else
@@ -52,8 +60,8 @@ module ActionSchema
52
60
  schema[name] = { association: resolved_schema }
53
61
  end
54
62
 
55
- def computed(name, &block)
56
- schema[name] = { computed: true, value: block }
63
+ def computed(name, lambda_or_proc = nil, &block)
64
+ schema[name] = { computed: true, value: (lambda_or_proc || block) }
57
65
  end
58
66
 
59
67
  def fields(*names)
@@ -109,7 +117,7 @@ module ActionSchema
109
117
 
110
118
  result[transformed_key] =
111
119
  if config[:computed]
112
- instance_exec(record, context, &config[:value])
120
+ instance_exec(record, context, &Dalambda[config[:value]])
113
121
  elsif association = config[:association]
114
122
  associated_record_or_collection = record.public_send(key)
115
123
  if associated_record_or_collection.nil?
@@ -138,7 +146,7 @@ module ActionSchema
138
146
  hooks = self.class.public_send("#{type}_hooks") || []
139
147
  hooks.each do |hook|
140
148
  @transformed = nil
141
- instance_exec(data, &hook)
149
+ instance_exec(data, &Dalambda[hook])
142
150
  data = @transformed || data
143
151
  end
144
152
  data
@@ -21,19 +21,21 @@ module ActionSchema
21
21
  resolve_schema_context(self.class.default_schema_context)
22
22
  end
23
23
 
24
- def schema_for(record_or_collection, schema_name = :default, context: {}, &block)
24
+ def schema_for(record_or_collection, schema_name_or_proc = :default, context: {}, &block)
25
25
  combined_schema_context = schema_context.merge(resolve_schema_context(context))
26
26
 
27
27
  schema_definition =
28
28
  if block_given?
29
29
  Class.new(ActionSchema.configuration.base_class, &block)
30
- elsif schema_name.is_a?(Class)
31
- schema_name
30
+ elsif schema_name_or_proc.is_a?(Proc)
31
+ Class.new(ActionSchema.configuration.base_class, &Dalambda[schema_name_or_proc])
32
+ elsif schema_name_or_proc.is_a?(Class)
33
+ schema_name_or_proc
32
34
  else
33
- self.class.action_schemas[schema_name]
35
+ self.class.action_schemas[schema_name_or_proc]
34
36
  end
35
37
 
36
- raise ArgumentError, "Schema `#{schema_name}` not defined" unless schema_definition
38
+ raise ArgumentError, "Schema `#{schema_name_or_proc}` not defined" unless schema_definition
37
39
 
38
40
  schema_definition.new(record_or_collection, context: combined_schema_context, controller: self).render
39
41
  end
@@ -0,0 +1,27 @@
1
+ module ActionSchema
2
+ # Dalambda is a stupid name for a stupid class.
3
+ # Forces your lambdas to ignore extra arguments and blocks.
4
+ # Works with instance_exec, etc.
5
+ class Dalambda
6
+ def self.[](lambda_or_proc, &block)
7
+ new(lambda_or_proc || block)
8
+ end
9
+
10
+ def initialize(lambda_or_proc, &block)
11
+ @lambda = lambda_or_proc || block
12
+ raise ArgumentError, "You must provide a lambda, proc, or block" unless @lambda.is_a?(Proc)
13
+ end
14
+
15
+ def to_proc
16
+ da_actual_lambda = @lambda
17
+ arity = @lambda.arity
18
+ proc do |*args, &block|
19
+ if da_actual_lambda.parameters.any? { |type, _| type == :block }
20
+ instance_exec(*args.take(arity), block, &da_actual_lambda)
21
+ else
22
+ instance_exec(*args.take(arity), &da_actual_lambda)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionSchema
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
data/lib/action_schema.rb CHANGED
@@ -8,6 +8,7 @@ module ActionSchema
8
8
  end
9
9
 
10
10
  require_relative "action_schema/version"
11
+ require_relative "action_schema/dalambda"
11
12
  require_relative "action_schema/configuration"
12
13
  require_relative "action_schema/base"
13
14
  require_relative "action_schema/controller"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julien Negrotto
@@ -140,6 +140,7 @@ files:
140
140
  - lib/action_schema/base.rb
141
141
  - lib/action_schema/configuration.rb
142
142
  - lib/action_schema/controller.rb
143
+ - lib/action_schema/dalambda.rb
143
144
  - lib/action_schema/railtie.rb
144
145
  - lib/action_schema/version.rb
145
146
  - sig/action_schema.rbs