restaurant 0.0.7 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +44 -73
- data/lib/restaurant.rb +2 -13
- data/lib/restaurant/actions.rb +52 -0
- data/lib/restaurant/router.rb +80 -14
- data/lib/restaurant/version.rb +1 -1
- metadata +8 -73
- data/lib/restaurant/authentication.rb +0 -7
- data/lib/restaurant/authorization.rb +0 -13
- data/lib/restaurant/config.rb +0 -43
- data/lib/restaurant/controller_helper.rb +0 -14
- data/lib/restaurant/controller_provider.rb +0 -8
- data/lib/restaurant/params_query_responder.rb +0 -8
- data/lib/restaurant/params_query_translator.rb +0 -170
- data/lib/restaurant/railtie.rb +0 -6
- data/lib/restaurant/restful_actions.rb +0 -67
- data/lib/restaurant/role_provider.rb +0 -93
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49cc226f4daf8e7f58cd29786cbc7791ede0710a
|
4
|
+
data.tar.gz: e674d4933f37fab45fe0ed45f8d63910a04b8077
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2df6791bafce8d9db067d18e6e8d71dfab0c4133ca5e4cb512e3137b0caa4c54d17a835a197656797f06bd863f2aa7a157304784c77c673cea60595b5c7bca84
|
7
|
+
data.tar.gz: c5e1e05f9dc39dde654c58aed854d4cff560fd0be8582d47d0f2735178e7cda6e958b447de550050a69645394aed9953f2fc6bdccfdfc1d3770112aa694dae18
|
data/README.md
CHANGED
@@ -1,87 +1,58 @@
|
|
1
1
|
# Restaurant
|
2
2
|
Restaurant serves your data via auto-defined RESTful API on your rails application.
|
3
|
-
All you have to do is to
|
3
|
+
All you have to do is to edit config/routes.rb.
|
4
4
|
|
5
|
-
##
|
6
|
-
* Auto-defined models
|
7
|
-
* Auto-defined controllers
|
8
|
-
* Auto-defined routes
|
9
|
-
* Versioning
|
10
|
-
* SQL-like URI query
|
11
|
-
* OAuth authentication
|
12
|
-
* Scope based authorization
|
13
|
-
* restrict actions
|
14
|
-
* restrict attributes
|
15
|
-
* restrict filtering
|
16
|
-
* restrict sorting
|
17
|
-
* RESTful APIs
|
18
|
-
* GET /v1/:resources
|
19
|
-
* GET /v1/:resources/:id
|
20
|
-
* POST /v1/:resources
|
21
|
-
* PUT /v1/:resources/:id
|
22
|
-
* DELETE /v1/:resources/:id
|
23
|
-
|
24
|
-
## Auto-defined application
|
25
|
-
Models, controllers, and routes are auto-defined from your config/restaurant.yml.
|
26
|
-
|
27
|
-
```yaml
|
28
|
-
# config/restaurant.yml
|
29
|
-
v1: # Namespaced by v1
|
30
|
-
public: # User with "public" scope token
|
31
|
-
recipes: #
|
32
|
-
actions: #
|
33
|
-
- show # can access to /recipes/:id
|
34
|
-
attributes: #
|
35
|
-
- title # can read recipe.title
|
36
|
-
admin: # User with "admin" scope token
|
37
|
-
recipes: #
|
38
|
-
actions: #
|
39
|
-
- index # can access to /recipes
|
40
|
-
- show # can access to /recipes/:id
|
41
|
-
where: #
|
42
|
-
- id # can filter recipes by id
|
43
|
-
- title # can filter recipes by title
|
44
|
-
order: #
|
45
|
-
- id # can sort recipes by id
|
46
|
-
- title # can sort recipes by title
|
47
|
-
attributes: #
|
48
|
-
- id # can read recipe.id
|
49
|
-
- title # can read recipe.title
|
5
|
+
## Get started
|
50
6
|
```
|
7
|
+
$ rails new example
|
8
|
+
$ cd example
|
51
9
|
|
52
|
-
|
53
|
-
|
10
|
+
$ vi Gemfile
|
11
|
+
source "https://rubygems.org"
|
12
|
+
gem "rails", "~> 3.2.13"
|
13
|
+
gem "restaurant"
|
14
|
+
gem "sqlite3"
|
54
15
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
response.should be_ok
|
60
|
-
response.body.should be_json(
|
61
|
-
"id" => 1,
|
62
|
-
"user_id" => 1
|
63
|
-
"body" => "body 1",
|
64
|
-
"title" => "title 1",
|
65
|
-
"updated_at" => "2000-01-01T00:00:00Z",
|
66
|
-
"created_at" => "2000-01-01T00:00:00Z",
|
67
|
-
)
|
16
|
+
$ vi config/routes.rb
|
17
|
+
Example::Application.routes.draw do
|
18
|
+
namespace :v1 do
|
19
|
+
Restaurant::Router.route(self)
|
68
20
|
end
|
69
21
|
end
|
70
|
-
```
|
71
22
|
|
72
|
-
|
73
|
-
|
74
|
-
# Gemfile
|
75
|
-
gem "restaurant"
|
76
|
-
```
|
23
|
+
$ brew install mongodb
|
24
|
+
$ mongod --fork
|
77
25
|
|
78
|
-
```
|
79
26
|
$ bundle install
|
80
|
-
$
|
81
|
-
$
|
82
|
-
|
83
|
-
|
84
|
-
|
27
|
+
$ rails g mongoid:config
|
28
|
+
$ rails c
|
29
|
+
|
30
|
+
[1] pry(main)> app.accept = "application/json"
|
31
|
+
=> "application/json"
|
32
|
+
[2] pry(main)> app.post "/v1/recipes.json", recipe: { title: "created" }
|
33
|
+
=> 201
|
34
|
+
[3] pry(main)> JSON.parse(app.response.body)
|
35
|
+
=> {"title"=>"created", "_id"=>"51963fe9f02da4c1f8000001"}
|
36
|
+
[4] pry(main)> app.get "/v1/recipes/51963fe9f02da4c1f8000001.json"
|
37
|
+
=> 200
|
38
|
+
[5] pry(main)> JSON.parse(app.response.body)
|
39
|
+
=> {"title"=>"created", "_id"=>"51963fe9f02da4c1f8000001"}
|
40
|
+
[6] pry(main)> app.put "/v1/recipes/51963fe9f02da4c1f8000001.json", recipe: { title: "updated" }
|
41
|
+
=> 204
|
42
|
+
[7] pry(main)> app.get "/v1/recipes/51963fe9f02da4c1f8000001.json"
|
43
|
+
=> 200
|
44
|
+
[8] pry(main)> JSON.parse(app.response.body)
|
45
|
+
=> {"title"=>"updated", "_id"=>"51963fe9f02da4c1f8000001"}
|
46
|
+
[9] pry(main)> app.get "/v1/recipes.json"
|
47
|
+
=> 200
|
48
|
+
[10] pry(main)> JSON.parse(app.response.body)
|
49
|
+
=> [{"title"=>"updated", "_id"=>"51963fe9f02da4c1f8000001"}]
|
50
|
+
[11] pry(main)> app.delete "/v1/recipes/51963fe9f02da4c1f8000001.json"
|
51
|
+
=> 204
|
52
|
+
[12] pry(main)> app.get "/v1/recipes.json"
|
53
|
+
=> 200
|
54
|
+
[13] pry(main)> JSON.parse(app.response.body)
|
55
|
+
=> []
|
85
56
|
```
|
86
57
|
|
87
58
|
## More
|
data/lib/restaurant.rb
CHANGED
@@ -1,14 +1,3 @@
|
|
1
|
-
require "
|
2
|
-
require "restaurant/
|
3
|
-
require "restaurant/config"
|
4
|
-
require "restaurant/controller_helper"
|
5
|
-
require "restaurant/controller_provider"
|
6
|
-
require "restaurant/params_query_responder"
|
7
|
-
require "restaurant/params_query_translator"
|
8
|
-
require "restaurant/restful_actions"
|
9
|
-
require "restaurant/role_provider"
|
1
|
+
require "mongoid"
|
2
|
+
require "restaurant/actions"
|
10
3
|
require "restaurant/router"
|
11
|
-
require "restaurant/railtie"
|
12
|
-
|
13
|
-
module Restaurant
|
14
|
-
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Restaurant
|
2
|
+
module Actions
|
3
|
+
def index
|
4
|
+
respond_with collection.find
|
5
|
+
end
|
6
|
+
|
7
|
+
def show
|
8
|
+
respond_with collection.find(:_id => resource_id).first
|
9
|
+
end
|
10
|
+
|
11
|
+
def create
|
12
|
+
collection.insert(resource_param.merge(:_id => resource_id))
|
13
|
+
respond_with collection.find(:_id => resource_id).first, :location => { :action => :show, :id => resource_id }
|
14
|
+
end
|
15
|
+
|
16
|
+
def update
|
17
|
+
respond_with collection.find(:_id => resource_id).update(:$set => resource_param)
|
18
|
+
end
|
19
|
+
|
20
|
+
def destroy
|
21
|
+
respond_with collection.find(:_id => resource_id).remove_all
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def collection
|
27
|
+
Mongoid.default_session.with(:safe => true)[resources_name]
|
28
|
+
end
|
29
|
+
|
30
|
+
def resource_name
|
31
|
+
resources_name.singularize
|
32
|
+
end
|
33
|
+
|
34
|
+
def resources_name
|
35
|
+
params[:resource]
|
36
|
+
end
|
37
|
+
|
38
|
+
def resource_param
|
39
|
+
params[resource_name]
|
40
|
+
end
|
41
|
+
|
42
|
+
def resource_id
|
43
|
+
@resource_id ||= begin
|
44
|
+
if params[:id]
|
45
|
+
Moped::BSON::ObjectId.from_string(params[:id])
|
46
|
+
else
|
47
|
+
Moped::BSON::ObjectId.new
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/restaurant/router.rb
CHANGED
@@ -1,23 +1,89 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# Define routes and a controller.
|
2
|
+
#
|
3
|
+
# Examples
|
4
|
+
#
|
5
|
+
# # config/routes.rb
|
6
|
+
# Restaurant::Router.route(self)
|
7
|
+
#
|
8
|
+
# 1. Define ResourcesController if not defined
|
9
|
+
# 2. Define these routes
|
10
|
+
# GET /:resources -> reosurces#index
|
11
|
+
# GET /:resources/:id -> resources#show
|
12
|
+
# POST /:resources -> resources#create
|
13
|
+
# PUT /:resources/:id -> resources#update
|
14
|
+
# DELETE /:resources/:id -> resources#destroy
|
15
|
+
#
|
16
|
+
#
|
17
|
+
# # config/routes.rb
|
18
|
+
# namespace :v1 do
|
19
|
+
# Restaurant::Router.route(self)
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# 1. Define V1::ResourcesController if not defined
|
23
|
+
# 2. Define these routes
|
24
|
+
# GET /v1/:resources -> v1/reosurces#index
|
25
|
+
# GET /v1/:resources/:id -> v1/resources#show
|
26
|
+
# POST /v1/:resources -> v1/resources#create
|
27
|
+
# PUT /v1/:resources/:id -> v1/resources#update
|
28
|
+
# DELETE /v1/:resources/:id -> v1/resources#destroy
|
29
|
+
#
|
30
|
+
module Restaurant
|
31
|
+
class Router
|
32
|
+
def self.route(*args)
|
33
|
+
new(*args).route
|
34
|
+
end
|
5
35
|
|
6
|
-
|
36
|
+
attr_reader :router
|
7
37
|
|
8
|
-
|
9
|
-
|
10
|
-
|
38
|
+
def initialize(router)
|
39
|
+
@router = router
|
40
|
+
end
|
11
41
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
42
|
+
def route
|
43
|
+
define_route
|
44
|
+
define_controller
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def define_route
|
50
|
+
router.instance_eval do
|
51
|
+
scope ":resource" do
|
52
|
+
controller :resources do
|
53
|
+
get "" => :index
|
54
|
+
get ":id" => :show
|
55
|
+
post "" => :create
|
56
|
+
put ":id" => :update
|
57
|
+
delete ":id" => :destroy
|
18
58
|
end
|
19
59
|
end
|
20
60
|
end
|
21
61
|
end
|
62
|
+
|
63
|
+
def define_controller
|
64
|
+
namespace.const_get(:ResourcesController)
|
65
|
+
rescue NameError
|
66
|
+
namespace.const_set(:ResourcesController, controller_class)
|
67
|
+
end
|
68
|
+
|
69
|
+
def scope
|
70
|
+
router.instance_variable_get(:@scope)
|
71
|
+
end
|
72
|
+
|
73
|
+
def controller_class
|
74
|
+
Class.new(::ApplicationController) do
|
75
|
+
include Restaurant::Actions
|
76
|
+
respond_to :json
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def namespace
|
81
|
+
scope[:module].to_s.camelize.constantize
|
82
|
+
rescue NameError => exception
|
83
|
+
if exception.to_s =~ /uninitialized constant (?:(.+)(?:::))?(.+)/
|
84
|
+
$1.to_s.constantize.const_set($2, Module.new)
|
85
|
+
retry
|
86
|
+
end
|
87
|
+
end
|
22
88
|
end
|
23
89
|
end
|
data/lib/restaurant/version.rb
CHANGED
metadata
CHANGED
@@ -1,31 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restaurant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-05-
|
11
|
+
date: 2013-05-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ~>
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 3.2.13
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ~>
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 3.2.13
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rack-accept-default
|
14
|
+
name: mongoid
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
17
|
- - '>='
|
@@ -39,33 +25,19 @@ dependencies:
|
|
39
25
|
- !ruby/object:Gem::Version
|
40
26
|
version: '0'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
28
|
+
name: rails
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
31
|
- - ~>
|
46
32
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
48
|
-
type: :
|
33
|
+
version: 3.2.13
|
34
|
+
type: :development
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
38
|
- - ~>
|
53
39
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: jquery-rails
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - '>='
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
40
|
+
version: 3.2.13
|
69
41
|
- !ruby/object:Gem::Dependency
|
70
42
|
name: sqlite3
|
71
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,20 +94,6 @@ dependencies:
|
|
122
94
|
- - '>='
|
123
95
|
- !ruby/object:Gem::Version
|
124
96
|
version: '0'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: factory_girl_rails
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ~>
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '4.0'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - ~>
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '4.0'
|
139
97
|
- !ruby/object:Gem::Dependency
|
140
98
|
name: simplecov
|
141
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,20 +108,6 @@ dependencies:
|
|
150
108
|
- - '>='
|
151
109
|
- !ruby/object:Gem::Version
|
152
110
|
version: '0'
|
153
|
-
- !ruby/object:Gem::Dependency
|
154
|
-
name: response_code_matchers
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
156
|
-
requirements:
|
157
|
-
- - '>='
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
version: '0'
|
160
|
-
type: :development
|
161
|
-
prerelease: false
|
162
|
-
version_requirements: !ruby/object:Gem::Requirement
|
163
|
-
requirements:
|
164
|
-
- - '>='
|
165
|
-
- !ruby/object:Gem::Version
|
166
|
-
version: '0'
|
167
111
|
description: Restraunt serves your data via auto-defined RESTful API on your rails
|
168
112
|
application.
|
169
113
|
email:
|
@@ -172,16 +116,7 @@ executables: []
|
|
172
116
|
extensions: []
|
173
117
|
extra_rdoc_files: []
|
174
118
|
files:
|
175
|
-
- lib/restaurant/
|
176
|
-
- lib/restaurant/authorization.rb
|
177
|
-
- lib/restaurant/config.rb
|
178
|
-
- lib/restaurant/controller_helper.rb
|
179
|
-
- lib/restaurant/controller_provider.rb
|
180
|
-
- lib/restaurant/params_query_responder.rb
|
181
|
-
- lib/restaurant/params_query_translator.rb
|
182
|
-
- lib/restaurant/railtie.rb
|
183
|
-
- lib/restaurant/restful_actions.rb
|
184
|
-
- lib/restaurant/role_provider.rb
|
119
|
+
- lib/restaurant/actions.rb
|
185
120
|
- lib/restaurant/router.rb
|
186
121
|
- lib/restaurant/version.rb
|
187
122
|
- lib/restaurant.rb
|
data/lib/restaurant/config.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
module Restaurant::Config
|
2
|
-
class << self
|
3
|
-
def versions
|
4
|
-
@versions ||= YAML.load_file(path)
|
5
|
-
end
|
6
|
-
|
7
|
-
def path
|
8
|
-
Rails.root.join("config/restaurant.yml").tap do |path|
|
9
|
-
raise NoRolesError, "#{path} is not found" unless path.exist?
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def define_version_modules
|
14
|
-
version_module_names.each do |version_module_name|
|
15
|
-
unless Object.const_defined?(version_module_name)
|
16
|
-
Object.const_set(version_module_name, Module.new)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def define_controller_classes(base)
|
22
|
-
versions.each do |version, scopes|
|
23
|
-
scopes.each do |scope, controllers|
|
24
|
-
controllers.keys.each do |controller|
|
25
|
-
version_module = version.camelize.constantize
|
26
|
-
controller_class_name = "#{controller.camelize}Controller"
|
27
|
-
unless version_module.const_defined?(controller_class_name)
|
28
|
-
version_module.const_set(controller_class_name, Class.new(base))
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def version_module_names
|
36
|
-
versions.keys.map do |version_name|
|
37
|
-
version_name.camelize
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
NoRolesError = Class.new(StandardError)
|
43
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module Restaurant::ControllerHelper
|
2
|
-
extend ActiveSupport::Concern
|
3
|
-
|
4
|
-
included do
|
5
|
-
use Rack::AcceptDefault
|
6
|
-
include Restaurant::ControllerProvider
|
7
|
-
include Restaurant::RestfulActions
|
8
|
-
include Restaurant::Authentication
|
9
|
-
include Restaurant::Authorization
|
10
|
-
include Restaurant::RoleProvider
|
11
|
-
self.responder = Restaurant::ParamsQueryResponder
|
12
|
-
respond_to :json
|
13
|
-
end
|
14
|
-
end
|
@@ -1,8 +0,0 @@
|
|
1
|
-
class Restaurant::ParamsQueryResponder < ActionController::Responder
|
2
|
-
def initialize(controller, resources, options = {})
|
3
|
-
if resources.last.is_a? ActiveRecord::Relation
|
4
|
-
resources[-1] = Restaurant::ParamsQueryTranslator.translate(controller.params, resources.last)
|
5
|
-
end
|
6
|
-
super(controller, resources, options)
|
7
|
-
end
|
8
|
-
end
|
@@ -1,170 +0,0 @@
|
|
1
|
-
class Restaurant::ParamsQueryTranslator
|
2
|
-
def self.translate(*args)
|
3
|
-
new(*args).translate
|
4
|
-
end
|
5
|
-
|
6
|
-
attr_reader :params, :resources
|
7
|
-
|
8
|
-
def initialize(params, resources)
|
9
|
-
@params = params
|
10
|
-
@resources = resources
|
11
|
-
end
|
12
|
-
|
13
|
-
def translate
|
14
|
-
filters.inject(resources) do |result, filter|
|
15
|
-
filter.call(result)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def filters
|
20
|
-
where_filters + order_filters
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def where_filters
|
26
|
-
where.map do |column, value|
|
27
|
-
WhereFilter.new(column, value)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def order_filters
|
32
|
-
order.map do |column|
|
33
|
-
OrderFilter.new(column)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def where
|
38
|
-
params[:where] || {}
|
39
|
-
end
|
40
|
-
|
41
|
-
def order
|
42
|
-
case params[:order]
|
43
|
-
when String
|
44
|
-
[params[:order]]
|
45
|
-
else
|
46
|
-
[]
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
class WhereFilter
|
51
|
-
attr_reader :column, :value
|
52
|
-
|
53
|
-
def initialize(column, value)
|
54
|
-
@column = column
|
55
|
-
@value = value
|
56
|
-
end
|
57
|
-
|
58
|
-
def call(resources)
|
59
|
-
sections.inject(resources) do |relation, section|
|
60
|
-
relation.where("#{column} #{section.operator}", *section.operand)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
|
66
|
-
def sections
|
67
|
-
value.map do |operator, operand|
|
68
|
-
Section.new(operator, operand)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
class Section
|
73
|
-
attr_reader :raw_operator, :raw_operand
|
74
|
-
|
75
|
-
def initialize(raw_operator, raw_operand)
|
76
|
-
@raw_operator = raw_operator
|
77
|
-
@raw_operand = raw_operand
|
78
|
-
end
|
79
|
-
|
80
|
-
def operator
|
81
|
-
if raw_operand.nil?
|
82
|
-
case raw_operator
|
83
|
-
when "eq"
|
84
|
-
"IS NULL"
|
85
|
-
when "ne"
|
86
|
-
"IS NOT NULL"
|
87
|
-
end
|
88
|
-
else
|
89
|
-
case raw_operator
|
90
|
-
when "eq"
|
91
|
-
"= ?"
|
92
|
-
when "ne"
|
93
|
-
"!= ?"
|
94
|
-
when "lt"
|
95
|
-
"< ?"
|
96
|
-
when "lte"
|
97
|
-
"<= ?"
|
98
|
-
when "gt"
|
99
|
-
"> ?"
|
100
|
-
when "gte"
|
101
|
-
">= ?"
|
102
|
-
when "in"
|
103
|
-
"IN (?)"
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def operand
|
109
|
-
case raw_operand
|
110
|
-
when nil
|
111
|
-
[]
|
112
|
-
else
|
113
|
-
[raw_operand]
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
class OrderFilter
|
120
|
-
attr_reader :columns
|
121
|
-
|
122
|
-
def initialize(columns)
|
123
|
-
@columns = columns
|
124
|
-
end
|
125
|
-
|
126
|
-
def call(resources)
|
127
|
-
sections.inject(resources) do |result, section|
|
128
|
-
result.order(section.sort)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def sections
|
133
|
-
Array.wrap(columns).map do |column|
|
134
|
-
Section.new(column)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
private
|
139
|
-
|
140
|
-
class Section
|
141
|
-
attr_reader :raw_column
|
142
|
-
|
143
|
-
def initialize(raw_column)
|
144
|
-
@raw_column = raw_column
|
145
|
-
end
|
146
|
-
|
147
|
-
def sort
|
148
|
-
"#{column} #{order}"
|
149
|
-
end
|
150
|
-
|
151
|
-
private
|
152
|
-
|
153
|
-
def column
|
154
|
-
raw_column.to_s.gsub(/^-/, "")
|
155
|
-
end
|
156
|
-
|
157
|
-
def order
|
158
|
-
if desc?
|
159
|
-
"DESC"
|
160
|
-
else
|
161
|
-
"ASC"
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
def desc?
|
166
|
-
/^-/ === raw_column.to_s
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
data/lib/restaurant/railtie.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
module Restaurant::RestfulActions
|
2
|
-
extend ActiveSupport::Concern
|
3
|
-
|
4
|
-
included do
|
5
|
-
rescue_from ActiveRecord::RecordNotFound do
|
6
|
-
head 404
|
7
|
-
end
|
8
|
-
|
9
|
-
hide_action :current_version
|
10
|
-
end
|
11
|
-
|
12
|
-
def index
|
13
|
-
respond_with model.scoped, :only => current_role.allowed_attributes
|
14
|
-
end
|
15
|
-
|
16
|
-
def show
|
17
|
-
respond_with resource, :only => current_role.allowed_attributes
|
18
|
-
end
|
19
|
-
|
20
|
-
def create
|
21
|
-
respond_with model.create(resource_param), :only => current_role.allowed_attributes
|
22
|
-
end
|
23
|
-
|
24
|
-
def update
|
25
|
-
respond_with resource.update_attributes(resource_param)
|
26
|
-
end
|
27
|
-
|
28
|
-
def destroy
|
29
|
-
respond_with resource.delete
|
30
|
-
end
|
31
|
-
|
32
|
-
def current_version
|
33
|
-
@current_version ||= self.class.name.split("::").first.underscore
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def model
|
39
|
-
model_name.constantize
|
40
|
-
rescue NameError
|
41
|
-
define_model
|
42
|
-
end
|
43
|
-
|
44
|
-
def model_name
|
45
|
-
self.class.name.sub(/Controller$/, "").singularize
|
46
|
-
end
|
47
|
-
|
48
|
-
def resource_param
|
49
|
-
params[resource_class_name.underscore]
|
50
|
-
end
|
51
|
-
|
52
|
-
def resource
|
53
|
-
model.find(params[:id])
|
54
|
-
end
|
55
|
-
|
56
|
-
def resource_class_name
|
57
|
-
model_name.split("::").last
|
58
|
-
end
|
59
|
-
|
60
|
-
def define_model
|
61
|
-
current_version_module.const_set(resource_class_name, Class.new(ActiveRecord::Base))
|
62
|
-
end
|
63
|
-
|
64
|
-
def current_version_module
|
65
|
-
current_version.camelize.constantize
|
66
|
-
end
|
67
|
-
end
|
@@ -1,93 +0,0 @@
|
|
1
|
-
module Restaurant::RoleProvider
|
2
|
-
private
|
3
|
-
|
4
|
-
def current_role
|
5
|
-
@current_role ||= Role.new(self)
|
6
|
-
end
|
7
|
-
|
8
|
-
class Role
|
9
|
-
delegate(
|
10
|
-
:action_name,
|
11
|
-
:controller_name,
|
12
|
-
:doorkeeper_token,
|
13
|
-
:params,
|
14
|
-
:to => :controller
|
15
|
-
)
|
16
|
-
|
17
|
-
attr_reader :controller
|
18
|
-
|
19
|
-
def initialize(controller)
|
20
|
-
@controller = controller
|
21
|
-
end
|
22
|
-
|
23
|
-
def has_authorization?
|
24
|
-
has_action_authorization? && has_query_authorization?
|
25
|
-
end
|
26
|
-
|
27
|
-
def abilities
|
28
|
-
@abilities ||= Restaurant::Config.versions[controller.current_version].map do |role, controllers|
|
29
|
-
if doorkeeper_token.scopes.include?(role.to_sym)
|
30
|
-
controllers[controller_name]
|
31
|
-
end
|
32
|
-
end.compact
|
33
|
-
end
|
34
|
-
|
35
|
-
def allowed_attributes
|
36
|
-
abilities.map {|ability| ability["attributes"] }.compact.inject(:|)
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def has_action_authorization?
|
42
|
-
abilities.any? do |ability|
|
43
|
-
ability["actions"].include?(action_name)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def has_query_authorization?
|
48
|
-
if has_not_allowed_where? || has_not_allowed_order?
|
49
|
-
false
|
50
|
-
else
|
51
|
-
true
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def has_where_query?
|
56
|
-
params[:where]
|
57
|
-
end
|
58
|
-
|
59
|
-
def has_order_query?
|
60
|
-
params[:order]
|
61
|
-
end
|
62
|
-
|
63
|
-
def order_abilities
|
64
|
-
abilities.inject([]) do |columns, ability|
|
65
|
-
columns + (ability["order"] || [])
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def where_abilities
|
70
|
-
abilities.inject([]) do |columns, ability|
|
71
|
-
columns + (ability["where"] || [])
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def has_not_allowed_where?
|
76
|
-
has_where_query? && (where_queries - where_abilities).any?
|
77
|
-
end
|
78
|
-
|
79
|
-
def has_not_allowed_order?
|
80
|
-
has_order_query? && (order_queries - order_abilities).any?
|
81
|
-
end
|
82
|
-
|
83
|
-
def where_queries
|
84
|
-
params[:where].keys
|
85
|
-
end
|
86
|
-
|
87
|
-
def order_queries
|
88
|
-
Array.wrap(params[:order]).map do |column|
|
89
|
-
column.sub(/^-/, "")
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|