trax_controller 0.1.2 → 0.1.4

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
- SHA1:
3
- metadata.gz: 2a0c3f89d4a18d3f4a2a657426d3cbbc171b2ebb
4
- data.tar.gz: a6c561ef139611f7428793d35e2020c04e47b5cb
2
+ SHA256:
3
+ metadata.gz: ed00dea1fdfcffa650fe001af13c9903a9e8cea3f8bcfaa1c944440c2ef8d293
4
+ data.tar.gz: f34a3dcd374fb0adddb5b126cc5e1f9a5ab69520ac1902e8b5399a2bf1e475cc
5
5
  SHA512:
6
- metadata.gz: 8233b8ef9a6fb515e44e666bc42af3749c1c00790e2fc094c88b0d0d1f45fdf5d8cf5da6045855fdb45e3f46385556022d6297f039eba32c64d7fa9168b0df2d
7
- data.tar.gz: 40c8a347d7552ba34035bf9264222b699d2ff0ae96d42762d401a06c20643017d8e2d98f1b18cd057ad0008db853b5d0fd65d60cd0723482bc6e040fbbd33f6e
6
+ metadata.gz: 9ff8023e73a5c5d27b0f337fccdc0f337fb5f4f91ec3e3ebbd5a4bce75c9fefa4c3373159848e86867ee3686e662e0eda6cec8814ac2f8cb830a5632731f34eb
7
+ data.tar.gz: 658915adb99f4b46f3fdb160abe4b217dccad146584df53949ddc47708ac3f9761bd7eb1baaae46e30d2b3d5619d4e998aa45a1380b38d31814bad7be55ba5b2
data/.gitignore CHANGED
@@ -7,8 +7,10 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ /vendor/
10
11
  *.bundle
11
12
  *.so
12
13
  *.o
13
14
  *.a
15
+ *.sqlite
14
16
  mkmf.log
data/Gemfile CHANGED
@@ -2,8 +2,6 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in trax_controller.gemspec
4
4
  gemspec
5
- # gem 'active_model_serializers', :github => 'rails-api/active_model_serializers', :branch => "0-10-stable"
6
- gem 'active_model_serializers', :github => 'rails-api/active_model_serializers', :branch => "0-10-stable", :ref => "6aba26049154712d65176708ffad55fcfe512ca0"
7
5
 
8
6
  group :test do
9
7
  gem 'activerecord'
@@ -88,6 +88,16 @@ module Trax
88
88
  collection_root.singularize
89
89
  end
90
90
 
91
+ #this overwrite allows a separate set of params to be used for create/update
92
+ #i.e. product_params_for_create, product_params_for_update
93
+ def resource_params_method_name
94
+ if respond_to?("#{resource_instance_name}_params_for_#{params[:action]}", true)
95
+ "#{resource_instance_name}_params_for_#{params[:action]}"
96
+ else
97
+ super
98
+ end
99
+ end
100
+
91
101
  #will set the resource instance var to whatever you pass it, then render
92
102
  def render_resource!(object, **options)
93
103
  instance_variable_set(:"@#{self.class.resources_configuration[:self][:instance_name]}", object)
@@ -108,6 +118,17 @@ module Trax
108
118
  render json: { meta: { errors: errors } }, status: status, serializer: nil
109
119
  end
110
120
 
121
+ def render_resource_action_response(success_status: 200, failure_status: :method_not_allowed, **options)
122
+ respond_with_dual_blocks(resource, options) do |success, failure|
123
+ success.json do
124
+ render_resource(success_status, **options)
125
+ end
126
+ failure.json do
127
+ render_errors(failure_status, **options)
128
+ end
129
+ end
130
+ end
131
+
111
132
  def resource_error_messages(resource: _resource, **options)
112
133
  return nil unless resource.errors.any?
113
134
 
@@ -0,0 +1,29 @@
1
+ module Trax
2
+ module Controller
3
+ module Collection
4
+ module NestedSearchScopes
5
+ extend ::ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+ def has_nested_scopes_for(scope_name, as:, model:, permitted_scopes: [], only: [:index, :search], type: :hash, **options)
9
+ has_scope(scope_name, as: as, only: only, type: type, **options) do |controller, scope, value|
10
+ scope_ivar_name = "@#{scope_name}_scope"
11
+ instance_variable_set(:"#{scope_ivar_name}", model)
12
+
13
+ value.each_pair do |k,v|
14
+ raise ::ActionController::ParameterMissing.new("Invalid search parameter #{k} #{v}") unless permitted_scopes.include?(k)
15
+
16
+ instance_variable_set(
17
+ :"#{scope_ivar_name}",
18
+ instance_variable_get(:"#{scope_ivar_name}").all.__send__(k, v)
19
+ )
20
+ end
21
+
22
+ scope.__send__(scope_name, instance_variable_get(:"#{scope_ivar_name}"))
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ module Trax
2
+ module Controller
3
+ module Collection
4
+ module Sortable
5
+ extend ::ActiveSupport::Concern
6
+
7
+ SORT_DIRECTIONS = [ "asc", "desc" ].freeze
8
+
9
+ module ClassMethods
10
+ def has_sort_scope(sort_scope_name, only: [:index, :search], type: :boolean, **options)
11
+ SORT_DIRECTIONS.each do |dir|
12
+ _sort_scope_name = :"#{sort_scope_name}_#{dir}"
13
+ has_scope(_sort_scope_name, only: only, type: type, **options)
14
+ end
15
+ end
16
+
17
+ def has_sort_scopes(*names, **options)
18
+ names.each{ |_name| has_sort_scope(_name, **options) }
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -4,8 +4,10 @@ module Trax
4
4
  extend ::ActiveSupport::Autoload
5
5
 
6
6
  autoload :Base
7
+ autoload :NestedSearchScopes
7
8
  autoload :ResponseMeta
8
9
  autoload :Searchable
10
+ autoload :Sortable
9
11
  autoload :Pageable
10
12
  end
11
13
  end
@@ -2,7 +2,7 @@ module Trax
2
2
  module Controller
3
3
  class Engine < ::Rails::Engine
4
4
  initializer 'trax_controller.active_model_serializers' do |app|
5
- ::ActiveModel::Serializer.config.adapter = Trax::Controller::Serialization::Adapters::Json
5
+ ::ActiveModel::Serializer.config.adapter = ::Trax::Controller::Serialization::Adapters::Json
6
6
  end
7
7
  end
8
8
  end
@@ -0,0 +1,54 @@
1
+ module Trax
2
+ module Controller
3
+ module PermitParamsFor
4
+ extend ::ActiveSupport::Concern
5
+
6
+ # Allows you to permit params by creating a Trax::Core::Types::Struct
7
+ # https://github.com/jasonayre/trax_core/blob/master/lib/trax/core/types/struct.rb
8
+ # permitted_params_for_action :create do
9
+ # string :title
10
+ # end
11
+
12
+ included do
13
+ class_attribute :trax_params_permitters
14
+ self.trax_params_permitters = {}
15
+ end
16
+
17
+ def params_permitter_for_action
18
+ action = params[:action]
19
+ return self.trax_params_permitters[action.to_sym] if self.trax_params_permitters.key?(action.to_sym)
20
+ return self.trax_params_permitters[:save] if self.trax_params_permitters.key?(:save) && (action == 'create' || action == 'update' || action == 'first_or_create')
21
+ raise StandardError.new("No param permitter defined for action #{action}")
22
+ end
23
+
24
+ def build_resource_params
25
+ _params = request.parameters[resource_request_name]
26
+ self.class.trax_params_permitters[action_name.to_sym].new(_params).to_serializable_hash
27
+ end
28
+
29
+ def build_resource
30
+ get_resource_ivar || set_resource_ivar(end_of_association_chain.send(method_for_build, resource_params))
31
+ end
32
+
33
+ def update_resource(object, attributes)
34
+ object.update(attributes)
35
+ end
36
+
37
+ module ClassMethods
38
+ def permitted_params_for_action(action_name, &block)
39
+ _klass = ::Trax::Core::NamedClass.new("#{self.name}::PermittedParamsForAction#{action_name.to_s.classify}", Trax::Core::Types::Struct, &block)
40
+ self.trax_params_permitters[action_name] = _klass
41
+ end
42
+
43
+ def permitted_params_for_save(&block)
44
+ _update_klass = ::Trax::Core::NamedClass.new("#{self.name}::PermittedParamsForActionUpdate", Trax::Core::Types::Struct, &block)
45
+ _create_klass = ::Trax::Core::NamedClass.new("#{self.name}::PermittedParamsForActionCreate", Trax::Core::Types::Struct, &block)
46
+ _first_or_create_klass = ::Trax::Core::NamedClass.new("#{self.name}::PermittedParamsForActionFirstOrCreate", Trax::Core::Types::Struct, &block)
47
+ self.trax_params_permitters[:update] = _update_klass
48
+ self.trax_params_permitters[:create] = _create_klass
49
+ self.trax_params_permitters[:first_or_create] = _first_or_create_klass
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,60 +1,11 @@
1
- # This adapter is a workaround for
2
- # https://github.com/rails-api/active_model_serializers/issues/835 until
3
- # https://github.com/rails-api/active_model_serializers/pull/952 is merged
4
-
5
1
  module Trax
6
2
  module Controller
7
3
  module Serialization
8
4
  module Adapters
9
- class Json < ActiveModel::Serializer::Adapter::Json
10
- def serializable_hash(options={})
11
- result = is_collection? ? collection_serializable_hash(options) : resource_serializable_hash(options)
12
- @options[:nested] ? result : { root => result }
13
- end
14
-
15
- private
16
-
17
- def get_hash(serializer, options={})
18
- self.class.new(serializer, :nested => true).serializable_hash(options)
19
- end
20
-
21
- def collection_serializable_hash(options={})
22
- serializer.map { |s| get_hash(s, options) }
23
- end
24
-
25
- def is_collection?
26
- serializer.respond_to?(:each)
27
- end
28
-
29
- def resource_serializable_hash(options={})
30
- cached = cache_check(serializer){ serializer.attributes(options) }
31
- resource_result = serialize_resource_associations
32
- cached.merge(resource_result)
33
- end
34
-
35
- def serialize_resource_associations
36
- resource_result = {}
37
-
38
- serializer.associations.each do |association|
39
- association_serializer = association.serializer
40
- association_options = association.options
41
-
42
- if association_serializer.respond_to?(:each)
43
- array_serializer = association_serializer
44
-
45
- resource_result[association.key] = array_serializer.map do |item|
46
- cache_check(item) { get_hash(item) }
47
- end
48
- else
49
- resource_result[association.key] = if association_serializer && association_serializer.object
50
- cache_check(association_serializer) { get_hash(association_serializer) }
51
- elsif association_options[:virtual_value]
52
- association_options[:virtual_value]
53
- end
54
- end
55
- end
56
-
57
- resource_result
5
+ class Json < ::ActiveModelSerializers::Adapter::Json
6
+ def initialize(serializer, options = {})
7
+ super
8
+ options[:include] = "**"
58
9
  end
59
10
  end
60
11
  end
@@ -24,6 +24,7 @@ module Trax
24
24
  autoload :Resource
25
25
  autoload :InheritResources
26
26
  autoload :ActionTypes
27
+ autoload :PermitParamsFor
27
28
  autoload :Serialization
28
29
 
29
30
  @configuration ||= ::Trax::Controller::Config.new
@@ -1,3 +1,3 @@
1
1
  module TraxController
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.4"
3
3
  end
@@ -33,6 +33,10 @@ class CategoriesController < ::ApplicationController
33
33
  show(serializer: ::CategoriesSerializer, root: 'show_by_calling_original_action')
34
34
  end
35
35
 
36
+ def product_with_category
37
+ render_resource(serializer: ::ProductWithCategorySerializer, root: 'product', resource: Product.find(params[:id]))
38
+ end
39
+
36
40
  private
37
41
 
38
42
  def category_params
@@ -2,7 +2,7 @@ class CategorySerializer < ::ActiveModel::Serializer
2
2
  attributes :name, :slug
3
3
 
4
4
  def slug
5
- name.parameterize('-')
5
+ object.name.parameterize('-')
6
6
  end
7
7
 
8
8
  has_many :products, :serializer => ::ProductSerializer
@@ -0,0 +1,4 @@
1
+ class CategoryWithSubcategorySerializer < ::ActiveModel::Serializer
2
+ attributes :name
3
+ has_many :subcategories, :serializer => CategoryWithSubcategorySerializer
4
+ end
@@ -0,0 +1,6 @@
1
+ require "category_with_subcategories_serializer"
2
+
3
+ class ProductWithCategorySerializer < ::ActiveModel::Serializer
4
+ attributes :name
5
+ has_one :category, :serializer => CategoryWithSubcategorySerializer
6
+ end
@@ -13,6 +13,7 @@ Rails.application.routes.draw do
13
13
  get 'show_by_calling_original_action'
14
14
  get 'widget'
15
15
  get 'widget_with_renamed_root'
16
+ get 'product_with_category'
16
17
  end
17
18
  end
18
19
  end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+
2
3
  describe ::Trax::Controller do
3
4
 
4
5
  end
@@ -2,11 +2,14 @@ require 'spec_helper'
2
2
 
3
3
  ::RSpec.describe CategoriesController, :type => :controller do
4
4
  before(:all) do
5
- @shoes_category = ::Category.create(:name => 'mens shoes')
6
- @watches_category = ::Category.create(:name => 'mens watches')
7
-
8
- @product1 = ::Product.create(:name => "DC Villan", :quantity => 0, :in_stock => false, :category => @shoes_category)
9
- @product2 = ::Product.create(:name => "Nixon Rotolog", :quantity => 2, :in_stock => true, :category => @watches_category)
5
+ @shoes_category = ::Category.create!(:name => 'mens shoes')
6
+ @watches_category = ::Category.create!(:name => 'mens watches')
7
+ @apparels_category = ::Category.create!(:name => 'mens apparels')
8
+ @shirts_category = @apparels_category.subcategories.create(:name => 'mens shirts')
9
+
10
+ @product1 = ::Product.create!(:name => "DC Villan", :quantity => 0, :in_stock => false, :category => @shoes_category)
11
+ @product2 = ::Product.create!(:name => "Nixon Rotolog", :quantity => 2, :in_stock => true, :category => @watches_category)
12
+ @product3 = ::Product.create!(:name => "T-Shirt", :quantity => 3, :in_stock => true, :category => @apparels_category)
10
13
  end
11
14
 
12
15
  context '#index' do
@@ -69,6 +72,24 @@ require 'spec_helper'
69
72
  expect(json["show_by_calling_original_action"]["name"]).to eq @shoes_category.name
70
73
  end
71
74
  end
75
+
76
+ describe "#product_with_category" do
77
+ it "deeply serializes" do
78
+ get :product_with_category, :id => @product3.id
79
+ json = ::JSON.parse(response.body)
80
+ expect(json["product"]).to eq(
81
+ "name" => @product3.name,
82
+ "category" => {
83
+ "name" => @apparels_category.name,
84
+ "subcategories" => [
85
+ { "name" => @shirts_category.name,
86
+ "subcategories" => []
87
+ }
88
+ ]
89
+ }
90
+ )
91
+ end
92
+ end
72
93
  end
73
94
 
74
95
  context '#create_with_modified_resource' do
@@ -1,15 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
- class NameCategorySerializer < ::ActiveModel::Serializer
4
- attributes :name
5
- has_many :subcategories, :serializer => NameCategorySerializer
6
- end
7
-
8
- class NameProductSerializer < ::ActiveModel::Serializer
9
- attributes :name
10
- has_one :category, :serializer => NameCategorySerializer
11
- end
12
-
13
3
  describe Trax::Controller::Serialization::Adapters::Json do
14
4
  let(:category_flat_heads){ ::Category.new(:name => "flat heads") }
15
5
  let(:category_screwdrivers){ ::Category.new(:name => "screwdrivers", :subcategories => [category_flat_heads]) }
@@ -17,7 +7,7 @@ describe Trax::Controller::Serialization::Adapters::Json do
17
7
  let(:category_tools){ ::Category.new(:name => "tools", :subcategories => [category_screwdrivers, category_knives]) }
18
8
  let(:product_tool){ ::Product.new(:name => "Generics Multi-Purpose Tool", :category => category_tools) }
19
9
  let(:root_key){ 'root_key' }
20
- let(:serializer){ ::NameProductSerializer.new(product_tool, :root => root_key) }
10
+ let(:serializer){ ::ProductWithCategorySerializer.new(product_tool, :root => root_key) }
21
11
  let!(:expected_root_key){ root_key.to_sym }
22
12
  let!(:expected_tool_hash){ {
23
13
  :name => product_tool.name,
@@ -40,7 +30,7 @@ describe Trax::Controller::Serialization::Adapters::Json do
40
30
  let(:category_cookware){ ::Category.new(:name => "cookware") }
41
31
  let(:product_pot){ ::Product.new(:name => "Pot", :category => category_cookware) }
42
32
  let(:collection){ [product_tool, product_pot] }
43
- let!(:expected_root_key){ root_key.pluralize.to_sym }
33
+ let(:root_key){ 'root_keys' }
44
34
  let!(:expected_pot_hash){ {
45
35
  :name => product_pot.name,
46
36
  :category => {
@@ -48,7 +38,7 @@ describe Trax::Controller::Serialization::Adapters::Json do
48
38
  :subcategories => []
49
39
  }
50
40
  }}
51
- let(:serializer){ ::ActiveModel::Serializer::ArraySerializer.new(collection, :root => root_key, :serializer => ::NameProductSerializer) }
41
+ let(:serializer){ ::ActiveModel::Serializer::CollectionSerializer.new(collection, :root => root_key, :serializer => ::ProductWithCategorySerializer) }
52
42
 
53
43
  it { expect(serialized).to eq(expected_root_key => [expected_tool_hash, expected_pot_hash]) }
54
44
  end
@@ -12,12 +12,14 @@ Gem::Specification.new do |spec|
12
12
  spec.description = %q{Resourceful, standardized controllers}
13
13
  spec.homepage = "http://www.github.com/jasonayre"
14
14
  spec.license = "MIT"
15
+ spec.required_ruby_version = '<= 3.0'
15
16
 
16
17
  spec.files = `git ls-files -z`.split("\x0")
17
18
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
20
  spec.require_paths = ["lib"]
20
21
 
22
+ spec.add_dependency "active_model_serializers", "~> 0.10"
21
23
  spec.add_dependency "trax_core"
22
24
  spec.add_dependency "will_paginate"
23
25
  spec.add_dependency "has_scope"
@@ -35,7 +37,8 @@ Gem::Specification.new do |spec|
35
37
  spec.add_development_dependency 'rspec-collection_matchers', '~> 1'
36
38
  spec.add_development_dependency 'guard', '~> 2'
37
39
  spec.add_development_dependency 'guard-bundler', '~> 2'
38
- spec.add_development_dependency 'rb-fsevent'
40
+ spec.add_development_dependency 'listen', '~> 3.0.3'
41
+ spec.add_development_dependency 'rb-fsevent', '~> 0.9.6'
39
42
  spec.add_development_dependency 'terminal-notifier-guard'
40
43
  spec.add_development_dependency 'pundit'
41
44
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trax_controller
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Ayre
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-22 00:00:00.000000000 Z
11
+ date: 2024-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: active_model_serializers
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.10'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.10'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: trax_core
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -248,20 +262,34 @@ dependencies:
248
262
  - - "~>"
249
263
  - !ruby/object:Gem::Version
250
264
  version: '2'
265
+ - !ruby/object:Gem::Dependency
266
+ name: listen
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - "~>"
270
+ - !ruby/object:Gem::Version
271
+ version: 3.0.3
272
+ type: :development
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - "~>"
277
+ - !ruby/object:Gem::Version
278
+ version: 3.0.3
251
279
  - !ruby/object:Gem::Dependency
252
280
  name: rb-fsevent
253
281
  requirement: !ruby/object:Gem::Requirement
254
282
  requirements:
255
- - - ">="
283
+ - - "~>"
256
284
  - !ruby/object:Gem::Version
257
- version: '0'
285
+ version: 0.9.6
258
286
  type: :development
259
287
  prerelease: false
260
288
  version_requirements: !ruby/object:Gem::Requirement
261
289
  requirements:
262
- - - ">="
290
+ - - "~>"
263
291
  - !ruby/object:Gem::Version
264
- version: '0'
292
+ version: 0.9.6
265
293
  - !ruby/object:Gem::Dependency
266
294
  name: terminal-notifier-guard
267
295
  requirement: !ruby/object:Gem::Requirement
@@ -327,12 +355,15 @@ files:
327
355
  - lib/trax/controller/authorize.rb
328
356
  - lib/trax/controller/collection.rb
329
357
  - lib/trax/controller/collection/base.rb
358
+ - lib/trax/controller/collection/nested_search_scopes.rb
330
359
  - lib/trax/controller/collection/pageable.rb
331
360
  - lib/trax/controller/collection/response_meta.rb
332
361
  - lib/trax/controller/collection/searchable.rb
362
+ - lib/trax/controller/collection/sortable.rb
333
363
  - lib/trax/controller/config.rb
334
364
  - lib/trax/controller/engine.rb
335
365
  - lib/trax/controller/inherit_resources.rb
366
+ - lib/trax/controller/permit_params_for.rb
336
367
  - lib/trax/controller/resource.rb
337
368
  - lib/trax/controller/resource/base.rb
338
369
  - lib/trax/controller/resource/response_meta.rb
@@ -352,7 +383,9 @@ files:
352
383
  - spec/internal/app/policies/widget_policy.rb
353
384
  - spec/internal/app/serializers/categories_serializer.rb
354
385
  - spec/internal/app/serializers/category_serializer.rb
386
+ - spec/internal/app/serializers/category_with_subcategories_serializer.rb
355
387
  - spec/internal/app/serializers/product_serializer.rb
388
+ - spec/internal/app/serializers/product_with_category_serializer.rb
356
389
  - spec/internal/app/serializers/widget_serializer.rb
357
390
  - spec/internal/config/database.yml
358
391
  - spec/internal/config/routes.rb
@@ -371,24 +404,23 @@ homepage: http://www.github.com/jasonayre
371
404
  licenses:
372
405
  - MIT
373
406
  metadata: {}
374
- post_install_message:
407
+ post_install_message:
375
408
  rdoc_options: []
376
409
  require_paths:
377
410
  - lib
378
411
  required_ruby_version: !ruby/object:Gem::Requirement
379
412
  requirements:
380
- - - ">="
413
+ - - "<="
381
414
  - !ruby/object:Gem::Version
382
- version: '0'
415
+ version: '3.0'
383
416
  required_rubygems_version: !ruby/object:Gem::Requirement
384
417
  requirements:
385
418
  - - ">="
386
419
  - !ruby/object:Gem::Version
387
420
  version: '0'
388
421
  requirements: []
389
- rubyforge_project:
390
- rubygems_version: 2.5.1
391
- signing_key:
422
+ rubygems_version: 3.5.9
423
+ signing_key:
392
424
  specification_version: 4
393
425
  summary: Resourceful, standardized controllers
394
426
  test_files:
@@ -403,7 +435,9 @@ test_files:
403
435
  - spec/internal/app/policies/widget_policy.rb
404
436
  - spec/internal/app/serializers/categories_serializer.rb
405
437
  - spec/internal/app/serializers/category_serializer.rb
438
+ - spec/internal/app/serializers/category_with_subcategories_serializer.rb
406
439
  - spec/internal/app/serializers/product_serializer.rb
440
+ - spec/internal/app/serializers/product_with_category_serializer.rb
407
441
  - spec/internal/app/serializers/widget_serializer.rb
408
442
  - spec/internal/config/database.yml
409
443
  - spec/internal/config/routes.rb