trax_controller 0.0.2 → 0.0.3
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 +4 -4
- data/.rspec +1 -0
- data/.travis.yml +7 -0
- data/Gemfile +7 -1
- data/Guardfile +37 -0
- data/config.ru +7 -0
- data/lib/Guardfile +38 -0
- data/lib/trax/controller/action_types.rb +29 -0
- data/lib/trax/controller/actions.rb +60 -26
- data/lib/trax/controller/collection/pageable.rb +47 -0
- data/lib/trax/controller/collection/searchable.rb +4 -14
- data/lib/trax/controller/collection.rb +1 -0
- data/lib/trax/controller/engine.rb +9 -0
- data/lib/trax/controller/resource/base.rb +0 -1
- data/lib/trax/controller/serialization/adapters/json.rb +63 -0
- data/lib/trax/controller/serialization/adapters.rb +11 -0
- data/lib/trax/controller/serialization.rb +9 -0
- data/lib/trax/controller.rb +10 -10
- data/lib/trax_controller/version.rb +1 -1
- data/spec/internal/app/controllers/application_controller.rb +2 -0
- data/spec/internal/app/controllers/categories_controller.rb +53 -0
- data/spec/internal/app/controllers/products_controller.rb +14 -0
- data/spec/internal/app/models/category.rb +5 -0
- data/spec/internal/app/models/product.rb +5 -0
- data/spec/internal/app/models/widget.rb +4 -0
- data/spec/internal/app/serializers/categories_serializer.rb +3 -0
- data/spec/internal/app/serializers/category_serializer.rb +9 -0
- data/spec/internal/app/serializers/product_serializer.rb +3 -0
- data/spec/internal/app/serializers/widget_serializer.rb +3 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/routes.rb +17 -0
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/internal/db/schema.rb +61 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/spec_helper.rb +12 -5
- data/spec/trax/controller_spec.rb +1 -4
- data/spec/trax/controllers/categories_controller_spec.rb +206 -0
- data/spec/trax/controllers/products_controller_spec.rb +40 -0
- data/trax_controller.gemspec +4 -0
- metadata +92 -4
- data/lib/trax/controller/resource/errors.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bdbaf7390613351761a1a3babb39b491bcdf7b1d
|
4
|
+
data.tar.gz: ea407ce95d7f6a417606e8ea8a022bc4f49ce392
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98358ac5bc8959c7abd30f3c8a80b1eeeeba40a25944997ee70e70a864940b4d6a35bd61b8304be3b3c730b740cbb7f6e7a209a04ed6313e9d63b1f040b3ff49
|
7
|
+
data.tar.gz: 821754fbed325e38de212341e8b6b6bbd583a248debf91b75edf3278fef22d7754a2fc8824243b10de9dec1c165da376c748f8be44999269987b7c155d8f3653
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -1,5 +1,11 @@
|
|
1
|
-
|
2
1
|
source 'https://rubygems.org'
|
3
2
|
|
4
3
|
# Specify your gem's dependencies in trax_controller.gemspec
|
5
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
|
+
|
8
|
+
group :test do
|
9
|
+
gem 'activerecord'
|
10
|
+
gem 'rspec-rails'
|
11
|
+
end
|
data/Guardfile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard :bundler do
|
5
|
+
watch('Gemfile')
|
6
|
+
# Uncomment next line if your Gemfile contains the `gemspec' command.
|
7
|
+
# watch(/^.+\.gemspec/)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
11
|
+
# rspec may be run, below are examples of the most common uses.
|
12
|
+
# * bundler: 'bundle exec rspec'
|
13
|
+
# * bundler binstubs: 'bin/rspec'
|
14
|
+
# * spring: 'bin/rsspec' (This will use spring if running and you have
|
15
|
+
# installed the spring binstubs per the docs)
|
16
|
+
# * zeus: 'zeus rspec' (requires the server to be started separetly)
|
17
|
+
# * 'just' rspec: 'rspec'
|
18
|
+
guard :rspec, cmd: 'bundle exec rspec' do
|
19
|
+
watch(%r{^spec/.+_spec\.rb$})
|
20
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
21
|
+
watch('spec/spec_helper.rb') { "spec" }
|
22
|
+
|
23
|
+
# Rails example
|
24
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
25
|
+
watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
26
|
+
watch(%r{^spec/internal/app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/trax/controllers/#{m[1]}_controller_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
27
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
28
|
+
watch('config/routes.rb') { "spec/routing" }
|
29
|
+
watch('spec/rails_helper.rb') { "spec" }
|
30
|
+
|
31
|
+
# Capybara features specs
|
32
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
|
33
|
+
|
34
|
+
# Turnip features and steps
|
35
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
36
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
37
|
+
end
|
data/config.ru
ADDED
data/lib/Guardfile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard :bundler do
|
5
|
+
watch('Gemfile')
|
6
|
+
# Uncomment next line if your Gemfile contains the `gemspec' command.
|
7
|
+
# watch(/^.+\.gemspec/)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
11
|
+
# rspec may be run, below are examples of the most common uses.
|
12
|
+
# * bundler: 'bundle exec rspec'
|
13
|
+
# * bundler binstubs: 'bin/rspec'
|
14
|
+
# * spring: 'bin/rsspec' (This will use spring if running and you have
|
15
|
+
# installed the spring binstubs per the docs)
|
16
|
+
# * zeus: 'zeus rspec' (requires the server to be started separetly)
|
17
|
+
# * 'just' rspec: 'rspec'
|
18
|
+
guard :rspec, cmd: 'bundle exec rspec' do
|
19
|
+
watch(%r{^spec/.+_spec\.rb$})
|
20
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
21
|
+
watch('spec/spec_helper.rb') { "spec" }
|
22
|
+
|
23
|
+
# Rails example
|
24
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
25
|
+
watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
26
|
+
watch(%r{^spec/internal/app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/trax/controllers/#{m[1]}_controller_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
27
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
28
|
+
watch('config/routes.rb') { "spec/routing" }
|
29
|
+
# watch('spec/internal/app/controllers/application_controller.rb') { "spec/controllers" }
|
30
|
+
watch('spec/rails_helper.rb') { "spec" }
|
31
|
+
|
32
|
+
# Capybara features specs
|
33
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
|
34
|
+
|
35
|
+
# Turnip features and steps
|
36
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
37
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
38
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Trax
|
2
|
+
module Controller
|
3
|
+
module ActionTypes
|
4
|
+
extend ::ActiveSupport::Concern
|
5
|
+
#todo: pretty janky but works for now
|
6
|
+
|
7
|
+
included do
|
8
|
+
class_attribute :action_types
|
9
|
+
|
10
|
+
self.action_types = Hashie::Mash.new({
|
11
|
+
:collection => [:index, :search],
|
12
|
+
:resource => [ :show, :delete, :update, :create, :login ]
|
13
|
+
})
|
14
|
+
end
|
15
|
+
|
16
|
+
def current_action
|
17
|
+
:"#{request.params["action"]}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def collection_action?
|
21
|
+
self.class.action_types[:collection].include?(current_action)
|
22
|
+
end
|
23
|
+
|
24
|
+
def resource_action?
|
25
|
+
self.class.action_types[:resource].include? current_action
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -7,80 +7,114 @@ module Trax
|
|
7
7
|
respond_to :json
|
8
8
|
end
|
9
9
|
|
10
|
-
def index
|
10
|
+
def index(collection: _collection, meta: collection_response_meta, serializer: collection_serializer, root: collection_root)
|
11
11
|
render :json => collection,
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
:meta => meta,
|
13
|
+
:each_serializer => serializer,
|
14
|
+
:root => root
|
15
15
|
end
|
16
16
|
|
17
|
-
|
17
|
+
#setting resource ivar stops it from trying to create via the default behavior
|
18
|
+
def create(success_status:201, failure_status: :unprocessable_entity, **options)
|
19
|
+
set_resource_ivar(options[:resource]) if options.has_key?(:resource)
|
20
|
+
|
18
21
|
create! do |success, failure|
|
19
22
|
success.json do
|
20
|
-
render_resource(
|
23
|
+
render_resource(success_status, **options)
|
21
24
|
end
|
22
25
|
|
23
26
|
failure.json do
|
24
|
-
render_errors(
|
27
|
+
render_errors(failure_status, **options)
|
25
28
|
end
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
29
|
-
def update
|
32
|
+
def update(success_status:200, failure_status: :unprocessable_entity, **options)
|
33
|
+
set_resource_ivar(options[:resource]) if options.has_key?(:resource)
|
34
|
+
|
30
35
|
update! do |success, failure|
|
31
36
|
success.json do
|
32
|
-
render_resource
|
37
|
+
render_resource(success_status, **options)
|
33
38
|
end
|
34
39
|
|
35
40
|
failure.json do
|
36
|
-
render_errors(
|
41
|
+
render_errors(failure_status, **options)
|
37
42
|
end
|
38
43
|
end
|
39
44
|
end
|
40
45
|
|
41
|
-
def destroy
|
46
|
+
def destroy(success_status:200, failure_status: :method_not_allowed, **options)
|
47
|
+
set_resource_ivar(options[:resource]) if options.has_key?(:resource)
|
48
|
+
|
42
49
|
destroy! do |success, failure|
|
43
50
|
success.json do
|
44
|
-
render_resource
|
51
|
+
render_resource(success_status, **options)
|
45
52
|
end
|
46
53
|
|
47
54
|
failure.json do
|
48
|
-
render_errors(
|
55
|
+
render_errors(failure_status, **options)
|
49
56
|
end
|
50
57
|
end
|
51
58
|
end
|
52
59
|
|
53
|
-
def show
|
54
|
-
render_resource
|
60
|
+
def show(*args, **options)
|
61
|
+
render_resource(*args, **options)
|
55
62
|
end
|
56
63
|
|
57
64
|
private
|
58
65
|
|
59
|
-
def
|
60
|
-
|
66
|
+
def collection_serializer
|
67
|
+
resource_serializer
|
61
68
|
end
|
62
69
|
|
63
|
-
def
|
64
|
-
|
65
|
-
render json: { meta: { errors: errors } }, status: status, serializer: nil
|
70
|
+
def collection_root
|
71
|
+
controller_name
|
66
72
|
end
|
67
73
|
|
68
|
-
|
69
|
-
|
74
|
+
#this is to avoid circular reference argument that we would otherwise get with render_resource
|
75
|
+
def _collection
|
76
|
+
collection
|
70
77
|
end
|
71
78
|
|
72
|
-
def
|
73
|
-
|
79
|
+
def _resource
|
80
|
+
resource
|
74
81
|
end
|
75
82
|
|
76
|
-
def
|
77
|
-
|
83
|
+
def resource_serializer
|
84
|
+
"#{resource_class.name.demodulize}Serializer".constantize
|
78
85
|
end
|
79
86
|
|
80
87
|
def resource_root
|
81
88
|
collection_root.singularize
|
82
89
|
end
|
83
90
|
|
91
|
+
#will set the resource instance var to whatever you pass it, then render
|
92
|
+
def render_resource!(object, **options)
|
93
|
+
instance_variable_set(:"@#{self.class.resources_configuration[:self][:instance_name]}", object)
|
94
|
+
render_resource(**options)
|
95
|
+
end
|
96
|
+
|
97
|
+
def render_resource(status = :ok, resource: _resource, serializer: resource_serializer, meta: resource_response_meta, scope: serialization_scope, root: resource_root)
|
98
|
+
render json: resource, serializer: serializer, meta: meta, status: status, scope: scope, root: root
|
99
|
+
end
|
100
|
+
|
101
|
+
def render_errors(status = :unprocessable_entity, error_messages_hash:{}, **options)
|
102
|
+
errors = error_messages_hash.merge(resource_error_messages(**options))
|
103
|
+
render json: { meta: { errors: errors } }, status: status, serializer: nil
|
104
|
+
end
|
105
|
+
|
106
|
+
def resource_error_messages(resource: _resource, **options)
|
107
|
+
return nil unless resource.errors.any?
|
108
|
+
|
109
|
+
resource.errors.inject({}) do |result, error|
|
110
|
+
field = "#{error[0]}"
|
111
|
+
message = error[1]
|
112
|
+
result[field] = message.downcase.include?(field) ? message : "#{field.titleize} #{message}"
|
113
|
+
result
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
#this metthod is in limbo because it appears this was removed from master branch of AMS?
|
84
118
|
def serialized_resource
|
85
119
|
@serialized_resource ||= resource_serializer.new(resource, scope: serialization_scope)
|
86
120
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Trax
|
2
|
+
module Controller
|
3
|
+
module Collection
|
4
|
+
module Pageable
|
5
|
+
extend ::ActiveSupport::Concern
|
6
|
+
|
7
|
+
PAGINATION_META_METHODS = [
|
8
|
+
:current_page,
|
9
|
+
:per_page,
|
10
|
+
:size,
|
11
|
+
:total_pages,
|
12
|
+
:total_entries
|
13
|
+
].freeze
|
14
|
+
|
15
|
+
included do
|
16
|
+
collection_defaults :page => 1, :per_page => 25
|
17
|
+
end
|
18
|
+
|
19
|
+
def pagination_params
|
20
|
+
params[:page] ||= self.class.collection_options.page
|
21
|
+
params[:per_page] ||= self.class.collection_options.per_page
|
22
|
+
|
23
|
+
@pagination_params ||= { :page => params[:page], :per_page => params[:per_page] }
|
24
|
+
end
|
25
|
+
|
26
|
+
def collection
|
27
|
+
@collection ||= super.paginate(pagination_params)
|
28
|
+
end
|
29
|
+
|
30
|
+
def collection_pagination_meta
|
31
|
+
@collection_pagination_meta ||= ::Trax::Controller::Collection::Pageable::PAGINATION_META_METHODS.inject({}) do |h, key|
|
32
|
+
h[key] = collection.try(key)
|
33
|
+
h
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def collection_response_meta
|
38
|
+
if collection_action?
|
39
|
+
super.merge!(:pagination => collection_pagination_meta)
|
40
|
+
else
|
41
|
+
super
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -4,22 +4,12 @@ module Trax
|
|
4
4
|
module Searchable
|
5
5
|
extend ::ActiveSupport::Concern
|
6
6
|
|
7
|
-
def search
|
8
|
-
|
9
|
-
:meta => collection_response_meta,
|
10
|
-
:each_serializer => collection_serializer,
|
11
|
-
:root => collection_root
|
7
|
+
def search(**options)
|
8
|
+
index(**options)
|
12
9
|
end
|
13
10
|
|
14
|
-
def
|
15
|
-
|
16
|
-
search_keys = self.class.scopes_configuration.keys
|
17
|
-
|
18
|
-
search_keys.inject(collection.all) do |result, key|
|
19
|
-
relation = params.has_key?("#{key}") ? result.__send__(key, params[key]) : result
|
20
|
-
relation
|
21
|
-
end.all
|
22
|
-
end
|
11
|
+
def collection_response_meta
|
12
|
+
super.merge!(:search_scopes => current_scopes)
|
23
13
|
end
|
24
14
|
end
|
25
15
|
end
|
@@ -0,0 +1,63 @@
|
|
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
|
+
module Trax
|
6
|
+
module Controller
|
7
|
+
module Serialization
|
8
|
+
module Adapters
|
9
|
+
class Json < ActiveModel::Serializer::Adapter::Json
|
10
|
+
def serializable_hash(options={})
|
11
|
+
is_collection? ? collection_serializable_hash(options) : resource_serializable_hash(options)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def collection_result
|
17
|
+
@collection_result ||= []
|
18
|
+
end
|
19
|
+
|
20
|
+
def collection_serializable_hash(options={})
|
21
|
+
_result = collection_result + serializer.map { |s| FlattenJson.new(s).serializable_hash(options) }
|
22
|
+
{ root => _result }
|
23
|
+
end
|
24
|
+
|
25
|
+
def is_collection?
|
26
|
+
serializer.respond_to?(:each)
|
27
|
+
end
|
28
|
+
|
29
|
+
def resource_result
|
30
|
+
@resource_result ||= {}
|
31
|
+
end
|
32
|
+
|
33
|
+
def resource_serializable_hash(options={})
|
34
|
+
cache_check(serializer){ resource_result.merge!(serializer.attributes(options)) }
|
35
|
+
serialize_resource_associations
|
36
|
+
{ root => resource_result }
|
37
|
+
end
|
38
|
+
|
39
|
+
def serialize_resource_associations
|
40
|
+
serializer.associations.each do |association|
|
41
|
+
association_serializer = association.serializer
|
42
|
+
association_options = association.options
|
43
|
+
|
44
|
+
if association_serializer.respond_to?(:each)
|
45
|
+
array_serializer = association_serializer
|
46
|
+
|
47
|
+
resource_result[association.key] = array_serializer.map do |item|
|
48
|
+
cache_check(item) { FlattenJson.new(item).serializable_hash }
|
49
|
+
end
|
50
|
+
else
|
51
|
+
resource_result[association.key] = if association_serializer && association_serializer.object
|
52
|
+
cache_check(association_serializer) { FlattenJson.new(association_serializer).serializable_hash }
|
53
|
+
elsif association_options[:virtual_value]
|
54
|
+
association_options[:virtual_value]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/trax/controller.rb
CHANGED
@@ -2,6 +2,9 @@ require 'hashie/dash'
|
|
2
2
|
require 'hashie/mash'
|
3
3
|
require 'trax_core'
|
4
4
|
require 'inherited_resources'
|
5
|
+
require 'will_paginate'
|
6
|
+
require 'active_model_serializers'
|
7
|
+
require 'has_scope'
|
5
8
|
|
6
9
|
module Trax
|
7
10
|
module Controller
|
@@ -14,22 +17,19 @@ module Trax
|
|
14
17
|
|
15
18
|
autoload :Actions
|
16
19
|
autoload :Collection
|
20
|
+
autoload :Engine
|
17
21
|
autoload :Resource
|
18
22
|
autoload :InheritResources
|
23
|
+
autoload :ActionTypes
|
24
|
+
autoload :Engine
|
25
|
+
autoload :Serialization
|
19
26
|
|
20
27
|
include ::Trax::Controller::InheritResources
|
21
28
|
include ::Trax::Controller::Collection::Base
|
22
29
|
include ::Trax::Controller::Resource::Base
|
23
30
|
include ::Trax::Controller::Actions
|
24
|
-
|
25
|
-
# inherit_resources
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
# included do
|
30
|
-
# inherit_resources
|
31
|
-
# end
|
32
|
-
|
33
|
-
|
31
|
+
include ::Trax::Controller::ActionTypes
|
34
32
|
end
|
35
33
|
end
|
34
|
+
|
35
|
+
::Trax::Controller::Engine if defined?(::Rails)
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class CategoriesController < ::ApplicationController
|
2
|
+
include ::Trax::Controller
|
3
|
+
include ::Trax::Controller::Collection::Pageable
|
4
|
+
|
5
|
+
defaults :resource_class => ::Category
|
6
|
+
|
7
|
+
has_scope :by_id
|
8
|
+
|
9
|
+
actions :index, :show, :create, :update, :destroy
|
10
|
+
|
11
|
+
def create_with_modified_response_codes
|
12
|
+
create(success_status: :accepted, failure_status: 404)
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_with_modified_resource
|
16
|
+
@widget = Widget.create(widget_params)
|
17
|
+
create(resource: @widget, root: 'widget', serializer: WidgetSerializer)
|
18
|
+
end
|
19
|
+
|
20
|
+
def show_without_products
|
21
|
+
render_resource(serializer: ::CategoriesSerializer)
|
22
|
+
end
|
23
|
+
|
24
|
+
def widget
|
25
|
+
render_resource(serializer: ::CategoriesSerializer, resource: Widget.new(:name => 'whatever'))
|
26
|
+
end
|
27
|
+
|
28
|
+
def widget_with_renamed_root
|
29
|
+
render_resource(serializer: ::CategoriesSerializer, root: 'widget', resource: Widget.new(:name => 'whatever'))
|
30
|
+
end
|
31
|
+
|
32
|
+
def show_by_calling_original_action
|
33
|
+
show(serializer: ::CategoriesSerializer, root: 'show_by_calling_original_action')
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def category_params
|
39
|
+
params.require(:category).permit(:name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def widget_params
|
43
|
+
params.require(:widget).permit(:name, :quantity)
|
44
|
+
end
|
45
|
+
|
46
|
+
def resource_serializer
|
47
|
+
::CategorySerializer
|
48
|
+
end
|
49
|
+
|
50
|
+
def collection_serializer
|
51
|
+
::CategoriesSerializer
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class ProductsController < ::ApplicationController
|
2
|
+
include ::Trax::Controller
|
3
|
+
include ::Trax::Controller::Collection::Pageable
|
4
|
+
|
5
|
+
defaults :resource_class => ::Product
|
6
|
+
|
7
|
+
has_scope :by_id
|
8
|
+
|
9
|
+
actions :index, :show, :create, :update, :destroy
|
10
|
+
|
11
|
+
def product_params
|
12
|
+
params.require(:product).permit(:name, :category_id)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
resources :products, :defaults => { :format => :json }
|
3
|
+
resources :categories, :defaults => { :format => :json } do
|
4
|
+
collection do
|
5
|
+
post 'create_with_modified_response_codes'
|
6
|
+
post 'create_with_modified_resource'
|
7
|
+
end
|
8
|
+
|
9
|
+
member do
|
10
|
+
delete 'destroy_with_modified_response_codes'
|
11
|
+
get 'show_without_products'
|
12
|
+
get 'show_by_calling_original_action'
|
13
|
+
get 'widget'
|
14
|
+
get 'widget_with_renamed_root'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
Binary file
|
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
::ActiveRecord::Schema.define do
|
3
|
+
create_table "products", :force => true do |t|
|
4
|
+
t.string "name"
|
5
|
+
t.integer "category_id"
|
6
|
+
t.integer "user_id"
|
7
|
+
t.decimal "price"
|
8
|
+
t.integer "quantity"
|
9
|
+
t.boolean "in_stock"
|
10
|
+
t.datetime "created_at", :null => false
|
11
|
+
t.datetime "updated_at", :null => false
|
12
|
+
end
|
13
|
+
|
14
|
+
create_table "categories", :force => true do |t|
|
15
|
+
t.string "name"
|
16
|
+
t.datetime "created_at", :null => false
|
17
|
+
t.datetime "updated_at", :null => false
|
18
|
+
end
|
19
|
+
|
20
|
+
create_table "users", :force => true do |t|
|
21
|
+
t.string "first_name"
|
22
|
+
t.string "last_name"
|
23
|
+
t.string "email"
|
24
|
+
t.datetime "created_at", :null => false
|
25
|
+
t.datetime "updated_at", :null => false
|
26
|
+
end
|
27
|
+
|
28
|
+
create_table "widgets", :force => true do |t|
|
29
|
+
t.string "uuid"
|
30
|
+
t.string "name"
|
31
|
+
t.string "subdomain"
|
32
|
+
t.string "website"
|
33
|
+
t.integer "status"
|
34
|
+
t.integer "quantity"
|
35
|
+
t.datetime "created_at", :null => false
|
36
|
+
t.datetime "updated_at", :null => false
|
37
|
+
end
|
38
|
+
|
39
|
+
create_table "people", :force => true do |t|
|
40
|
+
t.string "name"
|
41
|
+
t.string "uuid"
|
42
|
+
t.datetime "created_at", :null => false
|
43
|
+
t.datetime "updated_at", :null => false
|
44
|
+
end
|
45
|
+
|
46
|
+
create_table "staplers", :force => true do |t|
|
47
|
+
t.string "name"
|
48
|
+
t.string "type"
|
49
|
+
t.integer "attribute_set_id"
|
50
|
+
t.datetime "created_at", :null => false
|
51
|
+
t.datetime "updated_at", :null => false
|
52
|
+
end
|
53
|
+
|
54
|
+
create_table "swingline_stapler_attribute_sets", :force => true do |t|
|
55
|
+
t.float "speed"
|
56
|
+
t.string "owner"
|
57
|
+
|
58
|
+
t.datetime "created_at", :null => false
|
59
|
+
t.datetime "updated_at", :null => false
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
*.log
|
File without changes
|
data/spec/spec_helper.rb
CHANGED
@@ -1,18 +1,25 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'bundler'
|
3
|
+
require 'combustion'
|
4
|
+
require 'pry'
|
5
|
+
require 'active_record'
|
6
|
+
|
7
|
+
::Combustion.schema_format = :ruby
|
8
|
+
::Combustion.initialize! :all
|
9
|
+
|
10
|
+
require 'rspec/rails'
|
3
11
|
require 'simplecov'
|
4
12
|
require 'pry'
|
5
13
|
require 'trax_controller'
|
6
14
|
|
7
|
-
SimpleCov.start do
|
15
|
+
::SimpleCov.start do
|
8
16
|
add_filter '/spec/'
|
9
17
|
end
|
10
18
|
|
11
|
-
RSpec.configure do |config|
|
12
|
-
config.
|
13
|
-
end
|
19
|
+
::RSpec.configure do |config|
|
20
|
+
config.include RSpec::Rails::RequestExampleGroup, type: :feature
|
14
21
|
end
|
15
22
|
|
16
|
-
Bundler.require(:default, :development, :test)
|
23
|
+
::Bundler.require(:default, :development, :test)
|
17
24
|
|
18
25
|
::Dir["#{::File.dirname(__FILE__)}/support/*.rb"].each {|f| require f }
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
::RSpec.describe CategoriesController, :type => :controller do
|
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)
|
10
|
+
end
|
11
|
+
|
12
|
+
context '#index' do
|
13
|
+
it {
|
14
|
+
get :index
|
15
|
+
expect(response).to be_ok
|
16
|
+
json = ::JSON.parse(response.body)
|
17
|
+
expect(json).to have_key('categories')
|
18
|
+
}
|
19
|
+
|
20
|
+
context "serialization of associations" do
|
21
|
+
it {
|
22
|
+
get :index
|
23
|
+
json = ::JSON.parse(response.body)
|
24
|
+
expect(json["categories"][0]).to_not have_key('products')
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "#show" do
|
30
|
+
context "serialization of associations" do
|
31
|
+
it {
|
32
|
+
get :show, :id => @shoes_category.id
|
33
|
+
json = ::JSON.parse(response.body)
|
34
|
+
expect(json["category"]).to have_key('products')
|
35
|
+
expect(json["category"]["products"][0]["name"]).to eq("DC Villan")
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "overriding default resource actions and render resource" do
|
41
|
+
describe "#show_without_products" do
|
42
|
+
it {
|
43
|
+
get :show_without_products, :id => @shoes_category.id
|
44
|
+
json = ::JSON.parse(response.body)
|
45
|
+
expect(json["category"]).to_not have_key('products')
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#widget" do
|
50
|
+
it "render resource can have resource passed to it" do
|
51
|
+
get :widget, :id => @shoes_category.id
|
52
|
+
json = ::JSON.parse(response.body)
|
53
|
+
expect(json["category"]["name"]).to eq "whatever"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "#widget_with_renamed_root" do
|
58
|
+
it "allows root key to be overridden" do
|
59
|
+
get :widget_with_renamed_root, :id => @shoes_category.id
|
60
|
+
json = ::JSON.parse(response.body)
|
61
|
+
expect(json["widget"]["name"]).to eq "whatever"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#show_by_calling_original_action" do
|
66
|
+
it "allows show method itself to be called passing in overridden options" do
|
67
|
+
get :show_by_calling_original_action, :id => @shoes_category.id
|
68
|
+
json = ::JSON.parse(response.body)
|
69
|
+
expect(json["show_by_calling_original_action"]["name"]).to eq @shoes_category.name
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context '#create_with_modified_resource' do
|
75
|
+
let(:widget_name) { 'My New Widget' }
|
76
|
+
let(:widget_quantity) { 10 }
|
77
|
+
let(:params){ {
|
78
|
+
:format => :json,
|
79
|
+
:widget => widget_params
|
80
|
+
}}
|
81
|
+
let(:widget_params) { { :name => widget_name, :quantity => widget_quantity } }
|
82
|
+
before { post :create_with_modified_resource, params }
|
83
|
+
|
84
|
+
context 'success' do
|
85
|
+
it { expect(response).to be_successful }
|
86
|
+
it {
|
87
|
+
json = JSON.parse response.body
|
88
|
+
expect(json).to have_key("widget")
|
89
|
+
}
|
90
|
+
it { expect(response.status).to eq 201 }
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'failure' do
|
94
|
+
let(:widget_name) { 'My New Widget' }
|
95
|
+
let(:widget_quantity) { 0 }
|
96
|
+
|
97
|
+
context 'default failure action' do
|
98
|
+
before { post :create_with_modified_resource, params }
|
99
|
+
|
100
|
+
it { expect(response).to_not be_successful }
|
101
|
+
it {
|
102
|
+
json = JSON.parse response.body
|
103
|
+
expect(json["meta"]["errors"]).to have_key("quantity")
|
104
|
+
}
|
105
|
+
it { expect(response.status).to eq 422 }
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context '#create' do
|
111
|
+
let(:category_name) { 'My New Category'}
|
112
|
+
let(:params){ {
|
113
|
+
:format => :json,
|
114
|
+
:category => category_params
|
115
|
+
}}
|
116
|
+
let(:category_params) { { :name => category_name } }
|
117
|
+
|
118
|
+
context 'success' do
|
119
|
+
context 'with default create action' do
|
120
|
+
before { post :create, params }
|
121
|
+
|
122
|
+
it { expect(response).to be_successful }
|
123
|
+
it {
|
124
|
+
json = JSON.parse response.body
|
125
|
+
expect(json).to have_key("category")
|
126
|
+
}
|
127
|
+
it { expect(response.status).to eq 201 }
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'allows overrides' do
|
131
|
+
context 'response code override' do
|
132
|
+
before { post :create_with_modified_response_codes, params }
|
133
|
+
|
134
|
+
it { expect(response.status).to eq 202 }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'failure' do
|
140
|
+
let(:category_name) { 'a' }
|
141
|
+
|
142
|
+
context 'default create action' do
|
143
|
+
before { post :create, params }
|
144
|
+
|
145
|
+
it { expect(response).to_not be_successful }
|
146
|
+
it {
|
147
|
+
json = JSON.parse response.body
|
148
|
+
expect(json["meta"]["errors"]).to have_key("name")
|
149
|
+
}
|
150
|
+
it { expect(response.status).to eq 422 }
|
151
|
+
end
|
152
|
+
|
153
|
+
context 'allows overrides' do
|
154
|
+
context 'response code override' do
|
155
|
+
before { post :create_with_modified_response_codes, params }
|
156
|
+
|
157
|
+
it { expect(response.status).to eq 404 }
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context '#update' do
|
164
|
+
let(:category) { ::Category.create(:name => category_name) }
|
165
|
+
let(:category_name) { 'My New Category'}
|
166
|
+
let(:new_category_name) { 'mynewcategoryname' }
|
167
|
+
let(:params){ {
|
168
|
+
:format => :json,
|
169
|
+
:id => category.id,
|
170
|
+
:category => category_params
|
171
|
+
}}
|
172
|
+
let(:category_params) { { :name => new_category_name } }
|
173
|
+
|
174
|
+
context 'success' do
|
175
|
+
context 'with default update action' do
|
176
|
+
before { put(:update, params) }
|
177
|
+
|
178
|
+
it { expect(response).to be_successful }
|
179
|
+
it {
|
180
|
+
json = JSON.parse response.body
|
181
|
+
expect(json).to have_key("category")
|
182
|
+
}
|
183
|
+
it {
|
184
|
+
json = JSON.parse response.body
|
185
|
+
expect(json["category"]["name"]).to eq(new_category_name)
|
186
|
+
}
|
187
|
+
it { expect(response.status).to eq 200 }
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
context 'failure' do
|
192
|
+
let(:new_category_name) { 'a' }
|
193
|
+
|
194
|
+
context 'default update action' do
|
195
|
+
before { put :update, params }
|
196
|
+
|
197
|
+
it { expect(response).to_not be_successful }
|
198
|
+
it {
|
199
|
+
json = JSON.parse response.body
|
200
|
+
expect(json["meta"]["errors"]).to have_key("name")
|
201
|
+
}
|
202
|
+
it { expect(response.status).to eq 422 }
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
::RSpec.describe ProductsController, :type => :controller do
|
4
|
+
before(:all) do
|
5
|
+
@product1 = ::Product.create(:name => "apple imac", :quantity => 0, :in_stock => false)
|
6
|
+
@product2 = ::Product.create(:name => "apple macbook", :quantity => 2, :in_stock => true)
|
7
|
+
@product3 = ::Product.create(:name => "apple ipod", :quantity => 3, :in_stock => true)
|
8
|
+
end
|
9
|
+
|
10
|
+
context '#index' do
|
11
|
+
it {
|
12
|
+
get :index
|
13
|
+
expect(response).to be_ok
|
14
|
+
json = JSON.parse response.body
|
15
|
+
expect(json).to have_key('products')
|
16
|
+
}
|
17
|
+
|
18
|
+
context 'pagination' do
|
19
|
+
["current_page", "per_page", "size", "total_pages", "total_entries"].each do |k|
|
20
|
+
it {
|
21
|
+
get :index
|
22
|
+
json = JSON.parse response.body
|
23
|
+
expect(json["meta"]["pagination"]).to have_key(k)
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#show' do
|
32
|
+
it 'shows' do
|
33
|
+
get :show, id: @product1.id
|
34
|
+
|
35
|
+
expect(response).to be_ok
|
36
|
+
json = JSON.parse response.body
|
37
|
+
expect(json).to have_key('product')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/trax_controller.gemspec
CHANGED
@@ -19,8 +19,11 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_dependency "trax_core"
|
22
|
+
spec.add_dependency "will_paginate"
|
23
|
+
spec.add_dependency "has_scope"
|
22
24
|
spec.add_development_dependency "rails"
|
23
25
|
spec.add_development_dependency "inherited_resources"
|
26
|
+
spec.add_development_dependency 'combustion', '~> 0.5.3'
|
24
27
|
spec.add_development_dependency "bundler", "~> 1.6"
|
25
28
|
spec.add_development_dependency "rake"
|
26
29
|
spec.add_development_dependency "sqlite3"
|
@@ -35,4 +38,5 @@ Gem::Specification.new do |spec|
|
|
35
38
|
spec.add_development_dependency 'guard-bundler', '~> 2'
|
36
39
|
spec.add_development_dependency 'rb-fsevent'
|
37
40
|
spec.add_development_dependency 'terminal-notifier-guard'
|
41
|
+
|
38
42
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trax_controller
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Ayre
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-10-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: trax_core
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: will_paginate
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: has_scope
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: rails
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +80,20 @@ dependencies:
|
|
52
80
|
- - ">="
|
53
81
|
- !ruby/object:Gem::Version
|
54
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: combustion
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.5.3
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.5.3
|
55
97
|
- !ruby/object:Gem::Dependency
|
56
98
|
name: bundler
|
57
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -256,26 +298,54 @@ extensions: []
|
|
256
298
|
extra_rdoc_files: []
|
257
299
|
files:
|
258
300
|
- ".gitignore"
|
301
|
+
- ".rspec"
|
302
|
+
- ".travis.yml"
|
259
303
|
- Gemfile
|
304
|
+
- Guardfile
|
260
305
|
- LICENSE.txt
|
261
306
|
- README.md
|
262
307
|
- Rakefile
|
308
|
+
- config.ru
|
309
|
+
- lib/Guardfile
|
263
310
|
- lib/trax.rb
|
264
311
|
- lib/trax/controller.rb
|
312
|
+
- lib/trax/controller/action_types.rb
|
265
313
|
- lib/trax/controller/actions.rb
|
266
314
|
- lib/trax/controller/collection.rb
|
267
315
|
- lib/trax/controller/collection/base.rb
|
316
|
+
- lib/trax/controller/collection/pageable.rb
|
268
317
|
- lib/trax/controller/collection/response_meta.rb
|
269
318
|
- lib/trax/controller/collection/searchable.rb
|
319
|
+
- lib/trax/controller/engine.rb
|
270
320
|
- lib/trax/controller/inherit_resources.rb
|
271
321
|
- lib/trax/controller/resource.rb
|
272
322
|
- lib/trax/controller/resource/base.rb
|
273
|
-
- lib/trax/controller/resource/errors.rb
|
274
323
|
- lib/trax/controller/resource/response_meta.rb
|
324
|
+
- lib/trax/controller/serialization.rb
|
325
|
+
- lib/trax/controller/serialization/adapters.rb
|
326
|
+
- lib/trax/controller/serialization/adapters/json.rb
|
275
327
|
- lib/trax_controller.rb
|
276
328
|
- lib/trax_controller/version.rb
|
329
|
+
- spec/internal/app/controllers/application_controller.rb
|
330
|
+
- spec/internal/app/controllers/categories_controller.rb
|
331
|
+
- spec/internal/app/controllers/products_controller.rb
|
332
|
+
- spec/internal/app/models/category.rb
|
333
|
+
- spec/internal/app/models/product.rb
|
334
|
+
- spec/internal/app/models/widget.rb
|
335
|
+
- spec/internal/app/serializers/categories_serializer.rb
|
336
|
+
- spec/internal/app/serializers/category_serializer.rb
|
337
|
+
- spec/internal/app/serializers/product_serializer.rb
|
338
|
+
- spec/internal/app/serializers/widget_serializer.rb
|
339
|
+
- spec/internal/config/database.yml
|
340
|
+
- spec/internal/config/routes.rb
|
341
|
+
- spec/internal/db/combustion_test.sqlite
|
342
|
+
- spec/internal/db/schema.rb
|
343
|
+
- spec/internal/log/.gitignore
|
344
|
+
- spec/internal/public/favicon.ico
|
277
345
|
- spec/spec_helper.rb
|
278
346
|
- spec/trax/controller_spec.rb
|
347
|
+
- spec/trax/controllers/categories_controller_spec.rb
|
348
|
+
- spec/trax/controllers/products_controller_spec.rb
|
279
349
|
- trax_controller.gemspec
|
280
350
|
homepage: http://www.github.com/jasonayre
|
281
351
|
licenses:
|
@@ -297,10 +367,28 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
297
367
|
version: '0'
|
298
368
|
requirements: []
|
299
369
|
rubyforge_project:
|
300
|
-
rubygems_version: 2.4.
|
370
|
+
rubygems_version: 2.4.5
|
301
371
|
signing_key:
|
302
372
|
specification_version: 4
|
303
373
|
summary: Resourceful, standardized controllers
|
304
374
|
test_files:
|
375
|
+
- spec/internal/app/controllers/application_controller.rb
|
376
|
+
- spec/internal/app/controllers/categories_controller.rb
|
377
|
+
- spec/internal/app/controllers/products_controller.rb
|
378
|
+
- spec/internal/app/models/category.rb
|
379
|
+
- spec/internal/app/models/product.rb
|
380
|
+
- spec/internal/app/models/widget.rb
|
381
|
+
- spec/internal/app/serializers/categories_serializer.rb
|
382
|
+
- spec/internal/app/serializers/category_serializer.rb
|
383
|
+
- spec/internal/app/serializers/product_serializer.rb
|
384
|
+
- spec/internal/app/serializers/widget_serializer.rb
|
385
|
+
- spec/internal/config/database.yml
|
386
|
+
- spec/internal/config/routes.rb
|
387
|
+
- spec/internal/db/combustion_test.sqlite
|
388
|
+
- spec/internal/db/schema.rb
|
389
|
+
- spec/internal/log/.gitignore
|
390
|
+
- spec/internal/public/favicon.ico
|
305
391
|
- spec/spec_helper.rb
|
306
392
|
- spec/trax/controller_spec.rb
|
393
|
+
- spec/trax/controllers/categories_controller_spec.rb
|
394
|
+
- spec/trax/controllers/products_controller_spec.rb
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Trax
|
2
|
-
module Controller
|
3
|
-
module Resource
|
4
|
-
module Errors
|
5
|
-
extend ::ActiveSupport::Concern
|
6
|
-
|
7
|
-
def resource_errors?
|
8
|
-
resource.errors.any?
|
9
|
-
end
|
10
|
-
|
11
|
-
def resource_response_meta
|
12
|
-
if resource_action? && resource_errors?
|
13
|
-
super.merge!(:errors => resource.errors.messages)
|
14
|
-
else
|
15
|
-
super
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|