rails-rapido 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0c7c8672e3ca4ed53db33a2bb7345b9500428f5e
4
+ data.tar.gz: de8ef790022968819a797c831517886894e70c7d
5
+ SHA512:
6
+ metadata.gz: 0b1c4da043e6f9573eb6218440dd56f6ad4e0fc8117a1e8792fd4af4491deb4310fa37efbbffb05d40ed2324c8e08045f787a9d04aa415598fcd73784428d597
7
+ data.tar.gz: '082bd98d224b0ae9fa5979b008d87fe398184449a5c12509b48bd965b416f63f7f177736864c91af1fb38fc28cb45731917d4813d6895cd362ab00732ee4b865'
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.gem
data/.rubocop.yml ADDED
@@ -0,0 +1,124 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.3.4
3
+ # RuboCop has a bunch of cops enabled by default. This setting tells RuboCop
4
+ # to ignore them, so only the ones explicitly set in this file are enabled.
5
+ DisabledByDefault: true
6
+ Exclude:
7
+ - '**/templates/**/*'
8
+ - '**/vendor/**/*'
9
+ - 'actionpack/lib/action_dispatch/journey/parser.rb'
10
+
11
+ # Prefer &&/|| over and/or.
12
+ Style/AndOr:
13
+ Enabled: true
14
+
15
+ # Do not use braces for hash literals when they are the last argument of a
16
+ # method call.
17
+ Style/BracesAroundHashParameters:
18
+ Enabled: true
19
+
20
+ # Align `when` with `case`.
21
+ Style/CaseIndentation:
22
+ Enabled: true
23
+
24
+ # Align comments with method definitions.
25
+ Style/CommentIndentation:
26
+ Enabled: true
27
+
28
+ # No extra empty lines.
29
+ Style/EmptyLines:
30
+ Enabled: true
31
+
32
+ # In a regular class definition, no empty lines around the body.
33
+ Style/EmptyLinesAroundClassBody:
34
+ Enabled: true
35
+
36
+ # In a regular method definition, no empty lines around the body.
37
+ Style/EmptyLinesAroundMethodBody:
38
+ Enabled: true
39
+
40
+ # In a regular module definition, no empty lines around the body.
41
+ Style/EmptyLinesAroundModuleBody:
42
+ Enabled: true
43
+
44
+ # Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
45
+ Style/HashSyntax:
46
+ Enabled: true
47
+
48
+ # Method definitions after `private` or `protected` isolated calls need one
49
+ # extra level of indentation.
50
+ Style/IndentationConsistency:
51
+ Enabled: true
52
+ EnforcedStyle: rails
53
+
54
+ # Two spaces, no tabs (for indentation).
55
+ Style/IndentationWidth:
56
+ Enabled: true
57
+
58
+ Style/SpaceAfterColon:
59
+ Enabled: true
60
+
61
+ Style/SpaceAfterComma:
62
+ Enabled: true
63
+
64
+ Style/SpaceAroundEqualsInParameterDefault:
65
+ Enabled: true
66
+
67
+ Style/SpaceAroundKeyword:
68
+ Enabled: true
69
+
70
+ Style/SpaceAroundOperators:
71
+ Enabled: true
72
+
73
+ Style/SpaceBeforeFirstArg:
74
+ Enabled: true
75
+
76
+ # Defining a method with parameters needs parentheses.
77
+ Style/MethodDefParentheses:
78
+ Enabled: true
79
+
80
+ # Use `foo {}` not `foo{}`.
81
+ Style/SpaceBeforeBlockBraces:
82
+ Enabled: true
83
+
84
+ # Use `foo { bar }` not `foo {bar}`.
85
+ Style/SpaceInsideBlockBraces:
86
+ Enabled: true
87
+
88
+ # Use `{ a: 1 }` not `{a:1}`.
89
+ Style/SpaceInsideHashLiteralBraces:
90
+ Enabled: true
91
+
92
+ Style/SpaceInsideParens:
93
+ Enabled: true
94
+
95
+ # Check quotes usage according to lint rule below.
96
+ Style/StringLiterals:
97
+ Enabled: true
98
+ EnforcedStyle: single_quotes
99
+
100
+ # Detect hard tabs, no hard tabs.
101
+ Style/Tab:
102
+ Enabled: true
103
+
104
+ # Blank lines should not have any spaces.
105
+ Style/TrailingBlankLines:
106
+ Enabled: true
107
+
108
+ # No trailing whitespace.
109
+ Style/TrailingWhitespace:
110
+ Enabled: true
111
+
112
+ # Use quotes for string literals when they are enough.
113
+ Style/UnneededPercentQ:
114
+ Enabled: true
115
+
116
+ # Align `end` with the matching keyword or starting expression except for
117
+ # assignments, where it should be aligned with the LHS.
118
+ Lint/EndAlignment:
119
+ Enabled: true
120
+ EnforcedStyleAlignWith: variable
121
+
122
+ # Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
123
+ Lint/RequireParentheses:
124
+ Enabled: true
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # Rapido
2
+
3
+ Rapido is a simple module library that can be included into your Rails controllers to dry up a standard, RESTful API.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'rapido'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install rapido
20
+
21
+ ## Usage
22
+
23
+ Simply including the Rapido::Controller module into your controller is all you need to do if:
24
+
25
+ 1. Odd controller name: your controller's name follows the standard [Resource.pluralize]Controller format.
26
+ 1. Odd controller methods: you don't need any additional API endpoints other then the standard REST create/show/index/delete/update endpoints.
27
+ 1. Resource ownership: the resource governed by your controller is not nested within an owner, e.g. /api/v1/[parent_resource]/[parent_resource_id]/[my_resource]
28
+
29
+ If your controller has any of these characteristics, you'll need to do a little bit more work to properly configure your controller.
30
+
31
+ ### Odd controller name
32
+
33
+ If for some reason your controller name does not follow the standard format, you'll need to override the override the `resource_class` method. For example, if you have a controller named `MyOddleNamedWidgetController` for the `Widget` resource:
34
+
35
+ ```
36
+ class MyOddlyNamedWidgetController < ApplicationController
37
+ include Rapido::Controller
38
+
39
+ private
40
+
41
+ def resource_class
42
+ Widget
43
+ end
44
+ end
45
+ ```
46
+
47
+
48
+ ### Odd controller methods
49
+
50
+ If you have endpoints other than create, show, index, update, and delete, you can add them as additional methods like so:
51
+
52
+ ```
53
+ class WidgetsController < ApplicationController
54
+ include Rapido::Controller
55
+
56
+ def spin
57
+ resource.spin!
58
+ head :ok
59
+ end
60
+ end
61
+ ```
62
+
63
+ ### Resource ownership
64
+
65
+ If your resources has a `belongs_to` relationship that is reflected in the API route as a nested resource, you can specify the `resource_owner` class to include the relationship when retrieving the resource.
66
+
67
+ ```
68
+ class WidgetsController < ApplicationController
69
+ include Radido::Controller
70
+
71
+ resource_owner_name :widget_factory
72
+ end
73
+ ```
74
+
75
+ ## Development
76
+
77
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
78
+
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`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
80
+
81
+ ## Contributing
82
+
83
+ Bug reports and pull requests are welcome on GitHub at https://github.com/jskirst/rapido.
84
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler/gem_tasks'
2
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'rapido'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/rapido.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'rapido/version'
2
+ require 'rapido/controller'
3
+
4
+ module Rapido
5
+ end
@@ -0,0 +1,150 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext'
3
+ require 'active_support/rescuable'
4
+
5
+ module Rapido
6
+ module Controller
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ rescue_from ActiveRecord::RecordNotFound do |e|
11
+ render json: { errors: [ e.to_s ] }, status: 404
12
+ end
13
+ end
14
+
15
+ class_methods do
16
+ def resource_owner_name(name = nil)
17
+ @resource_owner_name = name.to_s if name
18
+ @resource_owner_name
19
+ end
20
+ end
21
+
22
+ def index
23
+ render json: { resource_name.pluralize => resource_collection.map(&:to_h), meta: index_meta }
24
+ end
25
+
26
+ def show
27
+ render json: resource.to_h
28
+ end
29
+
30
+ def create
31
+ new_resource = build_resource
32
+ if new_resource.save
33
+ render json: new_resource.to_h
34
+ else
35
+ render json: { errors: new_resource.errors.full_messages }, status: 422
36
+ end
37
+ end
38
+
39
+ def destroy
40
+ resource.destroy
41
+ head :ok
42
+ end
43
+
44
+ def update
45
+ resource.assign_attributes(resource_update_params)
46
+ if resource.save
47
+ render json: resource.to_h
48
+ else
49
+ render json: { errors: resource.errors.full_messages }, status: 422
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def index_meta
56
+ {
57
+ pagination: {
58
+ per_page: resource_collection.limit_value,
59
+ total_pages: resource_collection.total_pages,
60
+ total_objects: resource_collection.count,
61
+ }
62
+ }
63
+ end
64
+
65
+ def resource_required_param
66
+ resource_name.to_sym
67
+ end
68
+
69
+ def resource_create_permitted_params
70
+ []
71
+ end
72
+
73
+ def resource_update_permitted_params
74
+ []
75
+ end
76
+
77
+ def resource_update_params
78
+ params
79
+ .require(resource_required_param)
80
+ .permit(resource_update_permitted_params)
81
+ end
82
+
83
+ def resource_create_params
84
+ params
85
+ .require(resource_required_param)
86
+ .permit(resource_create_permitted_params)
87
+ end
88
+
89
+ def build_resource_params
90
+ {
91
+ resource_owner_reference.to_sym => resource_owner.id
92
+ }.merge(resource_create_params)
93
+ end
94
+
95
+ def build_resource
96
+ resource_class.new(build_resource_params)
97
+ end
98
+
99
+ def resource_collection
100
+ resource_class
101
+ .where("#{resource_owner_reference} = ?", resource_owner.id)
102
+ .page(params[:page])
103
+ end
104
+
105
+ def resource_owner_name
106
+ return self.class.resource_owner_name if self.class.resource_owner_name
107
+ @resource_owner_name ||= resource_owner.class.name.underscore
108
+ end
109
+
110
+ def resource_owner_class
111
+ @resource_owner_class ||= resource_owner_name.camelize.constantize
112
+ end
113
+
114
+ def resource_owner_reference
115
+ "#{resource_owner_name}_id"
116
+ end
117
+
118
+ def resource_owner
119
+ @resource_owner ||= resource_owner_class.find(params[resource_owner_reference])
120
+ end
121
+
122
+ def resource
123
+ @resource ||=
124
+ resource_class
125
+ .where("#{resource_owner_reference} = ?", resource_owner.id)
126
+ .find(params[:id])
127
+ end
128
+
129
+ def resource_reference
130
+ "#{resource_name}_id"
131
+ end
132
+
133
+ def resource_class
134
+ @resource_class ||=
135
+ resource_controller_class.constantize
136
+ end
137
+
138
+ def resource_name(name = nil)
139
+ return @resource_name = name if name
140
+ @resource_name ||= resource_controller_class.underscore
141
+ end
142
+
143
+ def resource_controller_class
144
+ @resource_controller_class ||=
145
+ self.class.name.split('::')[-1].remove('Controller').singularize
146
+ end
147
+
148
+ class ResourceOwnerNameNotSpecified < StandardError; end
149
+ end
150
+ end
@@ -0,0 +1,3 @@
1
+ module Rapido
2
+ VERSION = '0.1.0'
3
+ end
data/rapido.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rapido/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'rails-rapido'
8
+ spec.version = Rapido::VERSION
9
+ spec.authors = ['Jonathan Kirst']
10
+ spec.email = ['jskirst@gmail.com']
11
+ spec.license = 'MIT'
12
+
13
+ spec.summary = 'Rails API Dryer-o'
14
+ spec.description = 'Opinionated RESTfull API controller library.'
15
+ spec.homepage = 'https://github.com/jskirst/rapido'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = 'bin'
21
+ spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.14'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails-rapido
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jonathan Kirst
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-06-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Opinionated RESTfull API controller library.
42
+ email:
43
+ - jskirst@gmail.com
44
+ executables:
45
+ - console
46
+ - setup
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - ".gitignore"
51
+ - ".rubocop.yml"
52
+ - Gemfile
53
+ - README.md
54
+ - Rakefile
55
+ - bin/console
56
+ - bin/setup
57
+ - lib/rapido.rb
58
+ - lib/rapido/controller.rb
59
+ - lib/rapido/version.rb
60
+ - rapido.gemspec
61
+ homepage: https://github.com/jskirst/rapido
62
+ licenses:
63
+ - MIT
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.6.11
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: Rails API Dryer-o
85
+ test_files: []