sinatra-rest-api 0.1.3 → 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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/.rubocop.yml +34 -0
  4. data/Gemfile +20 -0
  5. data/Gemfile.lock +92 -0
  6. data/LICENSE +5 -0
  7. data/README.md +135 -0
  8. data/examples/active_record/Gemfile +15 -0
  9. data/examples/active_record/Gemfile.lock +75 -0
  10. data/examples/active_record/Rakefile +8 -0
  11. data/examples/active_record/app.rb +117 -0
  12. data/examples/active_record/config.ru +8 -0
  13. data/examples/active_record/database.yml +7 -0
  14. data/examples/active_record/db/migrate/001_create_authors.rb +11 -0
  15. data/examples/active_record/db/migrate/002_create_categories.rb +10 -0
  16. data/examples/active_record/db/migrate/003_create_books.rb +16 -0
  17. data/examples/active_record/db/migrate/004_create_tags.rb +10 -0
  18. data/examples/active_record/db/migrate/005_create_books_tags.rb +11 -0
  19. data/examples/active_record/db/migrate/006_create_chapters.rb +12 -0
  20. data/examples/active_record/db/schema.rb +61 -0
  21. data/examples/active_record/db/seeds.rb +0 -0
  22. data/examples/activeresource/Gemfile +10 -0
  23. data/examples/activeresource/Gemfile.lock +68 -0
  24. data/examples/activeresource/app.rb +125 -0
  25. data/examples/activeresource/config.ru +9 -0
  26. data/examples/activeresource/layout.slim +78 -0
  27. data/examples/misc/set_verb_options.rb +12 -0
  28. data/examples/mongoid/Gemfile +11 -0
  29. data/examples/mongoid/Gemfile.lock +68 -0
  30. data/examples/mongoid/Rakefile +3 -0
  31. data/examples/mongoid/app.rb +144 -0
  32. data/examples/mongoid/config.ru +8 -0
  33. data/examples/mongoid/database.yml +13 -0
  34. data/examples/mongoid/lib/tasks/db.rake +79 -0
  35. data/examples/ng-admin/index.html +168 -0
  36. data/examples/ng-admin/package.json +14 -0
  37. data/examples/sequel/Gemfile +14 -0
  38. data/examples/sequel/Gemfile.lock +54 -0
  39. data/examples/sequel/Rakefile +3 -0
  40. data/examples/sequel/app.rb +138 -0
  41. data/examples/sequel/config.ru +9 -0
  42. data/examples/sequel/database.yml +7 -0
  43. data/examples/sequel/db/migrate/001_create_authors.rb +15 -0
  44. data/examples/sequel/db/migrate/002_create_categories.rb +14 -0
  45. data/examples/sequel/db/migrate/003_create_books.rb +20 -0
  46. data/examples/sequel/db/migrate/004_create_tags.rb +14 -0
  47. data/examples/sequel/db/migrate/005_create_books_tags.rb +15 -0
  48. data/examples/sequel/db/migrate/006_create_chapters.rb +16 -0
  49. data/examples/sequel/lib/tasks/db.rake +44 -0
  50. data/lib/sinatra-rest-api/actions.rb +2 -1
  51. data/sinatra-rest-api.gemspec +24 -0
  52. data/spec/action_create_spec.rb +164 -0
  53. data/spec/action_delete_spec.rb +32 -0
  54. data/spec/action_list_spec.rb +31 -0
  55. data/spec/action_read_spec.rb +28 -0
  56. data/spec/action_update_spec.rb +98 -0
  57. data/spec/app_active_record_spec.rb +53 -0
  58. data/spec/app_mongoid_spec.rb +46 -0
  59. data/spec/app_sequel_spec.rb +45 -0
  60. data/spec/spec_helper.rb +59 -0
  61. metadata +70 -3
@@ -0,0 +1,8 @@
1
+ # config.ru (run with rackup)
2
+
3
+ # Launch with:
4
+ # rackup -o 0.0.0.0 -p 4567
5
+
6
+ require './app'
7
+
8
+ run ActiveRecordTest::App
@@ -0,0 +1,7 @@
1
+ development:
2
+ adapter: sqlite3
3
+ database: 'db/db.sqlite3'
4
+
5
+ test:
6
+ adapter: sqlite3
7
+ database: 'db/test.sqlite3'
@@ -0,0 +1,11 @@
1
+ # Authors
2
+ class CreateAuthors < ActiveRecord::Migration[4.2]
3
+ def change
4
+ create_table :authors do |t|
5
+ t.string :name, null: false
6
+ t.string :email, null: false
7
+ t.timestamp :created_at
8
+ t.timestamp :updated_at
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ # Categories
2
+ class CreateCategories < ActiveRecord::Migration[4.2]
3
+ def change
4
+ create_table :categories do |t|
5
+ t.string :name, null: false
6
+ t.timestamp :created_at
7
+ t.timestamp :updated_at
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ # Books
2
+ class CreateBooks < ActiveRecord::Migration[4.2]
3
+ def change
4
+ create_table :books do |t|
5
+ t.string :title, null: false
6
+ t.text :description
7
+ t.integer :pages
8
+ t.float :price
9
+ t.datetime :dt
10
+ t.integer :author_id
11
+ t.integer :category_id
12
+ t.timestamp :created_at
13
+ t.timestamp :updated_at
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ # Tags
2
+ class CreateTags < ActiveRecord::Migration[4.2]
3
+ def change
4
+ create_table :tags do |t|
5
+ t.string :name, null: false
6
+ t.timestamp :created_at
7
+ t.timestamp :updated_at
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ # BooksTags
2
+ class CreateBooksTags < ActiveRecord::Migration[4.2]
3
+ def change
4
+ create_table :books_tags do |t|
5
+ t.integer :book_id, null: false
6
+ t.integer :tag_id, null: false
7
+ t.timestamp :created_at
8
+ t.timestamp :updated_at
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ # Authors
2
+ class CreateChapters < ActiveRecord::Migration[4.2]
3
+ def change
4
+ create_table :chapters do |t|
5
+ t.string :title, null: false
6
+ t.integer :page
7
+ t.integer :book_id
8
+ t.timestamp :created_at
9
+ t.timestamp :updated_at
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,61 @@
1
+ # This file is auto-generated from the current state of the database. Instead
2
+ # of editing this file, please use the migrations feature of Active Record to
3
+ # incrementally modify your database, and then regenerate this schema definition.
4
+ #
5
+ # Note that this schema.rb definition is the authoritative source for your
6
+ # database schema. If you need to create the application database on another
7
+ # system, you should be using db:schema:load, not running all the migrations
8
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
10
+ #
11
+ # It's strongly recommended that you check this file into your version control system.
12
+
13
+ ActiveRecord::Schema.define(version: 6) do
14
+
15
+ create_table "authors", force: :cascade do |t|
16
+ t.string "name", null: false
17
+ t.string "email", null: false
18
+ t.datetime "created_at"
19
+ t.datetime "updated_at"
20
+ end
21
+
22
+ create_table "books", force: :cascade do |t|
23
+ t.string "title", null: false
24
+ t.text "description"
25
+ t.integer "pages"
26
+ t.float "price"
27
+ t.datetime "dt"
28
+ t.integer "author_id"
29
+ t.integer "category_id"
30
+ t.datetime "created_at"
31
+ t.datetime "updated_at"
32
+ end
33
+
34
+ create_table "books_tags", force: :cascade do |t|
35
+ t.integer "book_id", null: false
36
+ t.integer "tag_id", null: false
37
+ t.datetime "created_at"
38
+ t.datetime "updated_at"
39
+ end
40
+
41
+ create_table "categories", force: :cascade do |t|
42
+ t.string "name", null: false
43
+ t.datetime "created_at"
44
+ t.datetime "updated_at"
45
+ end
46
+
47
+ create_table "chapters", force: :cascade do |t|
48
+ t.string "title", null: false
49
+ t.integer "page"
50
+ t.integer "book_id"
51
+ t.datetime "created_at"
52
+ t.datetime "updated_at"
53
+ end
54
+
55
+ create_table "tags", force: :cascade do |t|
56
+ t.string "name", null: false
57
+ t.datetime "created_at"
58
+ t.datetime "updated_at"
59
+ end
60
+
61
+ end
File without changes
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'pry'
4
+ gem 'pry-rescue'
5
+
6
+ gem 'sinatra'
7
+ gem 'slim'
8
+ gem 'thin'
9
+
10
+ gem 'activeresource'
@@ -0,0 +1,68 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ activemodel (4.2.7.1)
5
+ activesupport (= 4.2.7.1)
6
+ builder (~> 3.1)
7
+ activeresource (4.1.0)
8
+ activemodel (~> 4.0)
9
+ activesupport (~> 4.0)
10
+ rails-observers (~> 0.1.2)
11
+ activesupport (4.2.7.1)
12
+ i18n (~> 0.7)
13
+ json (~> 1.7, >= 1.7.7)
14
+ minitest (~> 5.1)
15
+ thread_safe (~> 0.3, >= 0.3.4)
16
+ tzinfo (~> 1.1)
17
+ builder (3.2.2)
18
+ coderay (1.1.1)
19
+ daemons (1.2.4)
20
+ eventmachine (1.2.0.1)
21
+ i18n (0.7.0)
22
+ interception (0.5)
23
+ json (1.8.3)
24
+ method_source (0.8.2)
25
+ minitest (5.9.1)
26
+ pry (0.10.4)
27
+ coderay (~> 1.1.0)
28
+ method_source (~> 0.8.1)
29
+ slop (~> 3.4)
30
+ pry-rescue (1.4.4)
31
+ interception (>= 0.5)
32
+ pry
33
+ rack (1.6.4)
34
+ rack-protection (1.5.3)
35
+ rack
36
+ rails-observers (0.1.2)
37
+ activemodel (~> 4.0)
38
+ sinatra (1.4.7)
39
+ rack (~> 1.5)
40
+ rack-protection (~> 1.4)
41
+ tilt (>= 1.3, < 3)
42
+ slim (3.0.7)
43
+ temple (~> 0.7.6)
44
+ tilt (>= 1.3.3, < 2.1)
45
+ slop (3.6.0)
46
+ temple (0.7.7)
47
+ thin (1.7.0)
48
+ daemons (~> 1.0, >= 1.0.9)
49
+ eventmachine (~> 1.0, >= 1.0.4)
50
+ rack (>= 1, < 3)
51
+ thread_safe (0.3.5)
52
+ tilt (2.0.5)
53
+ tzinfo (1.2.2)
54
+ thread_safe (~> 0.1)
55
+
56
+ PLATFORMS
57
+ ruby
58
+
59
+ DEPENDENCIES
60
+ activeresource
61
+ pry
62
+ pry-rescue
63
+ sinatra
64
+ slim
65
+ thin
66
+
67
+ BUNDLED WITH
68
+ 1.13.5
@@ -0,0 +1,125 @@
1
+ require 'pry'
2
+
3
+ require 'sinatra/base'
4
+ require 'slim'
5
+ require 'activeresource'
6
+
7
+ # Active Resource Test client
8
+ module ActiveResourceTest
9
+ # Handle JSON response
10
+ class JsonFormatter
11
+ include ActiveResource::Formats::JsonFormat
12
+
13
+ attr_reader :collection_name
14
+
15
+ def initialize(collection_name)
16
+ @collection_name = collection_name.to_s
17
+ end
18
+
19
+ def decode(json)
20
+ remove_root(ActiveSupport::JSON.decode(json))
21
+ end
22
+
23
+ private
24
+
25
+ def remove_root(data)
26
+ if data.is_a?(Hash) && data[collection_name]
27
+ data[collection_name]
28
+ else
29
+ data
30
+ end
31
+ end
32
+ end
33
+
34
+ # Base class
35
+ class Base < ActiveResource::Base
36
+ self.site = 'http://localhost:3000'
37
+ self.include_root_in_json = true
38
+ self.format = JsonFormatter.new( :collection_name )
39
+ end
40
+
41
+ # Author class
42
+ class Writer < Base
43
+ # self.element_name = 'writer'
44
+ end
45
+
46
+ # Book class
47
+ class Book < Base; end
48
+
49
+ # Category class
50
+ class Category < Base; end
51
+
52
+ # Chapter class
53
+ class Chapter < Base; end
54
+
55
+ # Tag class
56
+ class Tag < Base; end
57
+
58
+ # Main class
59
+ class App < Sinatra::Application
60
+ configure do
61
+ set :port, 4000
62
+ set :views, settings.root
63
+ end
64
+
65
+ before do
66
+ @models ||= { writers: Writer, books: Book, categories: Category, chapters: Chapter, tags: Tag }
67
+ @links ||= [
68
+ [ '/', 'Main' ],
69
+ [ '/writers', 'Authors' ],
70
+ [ '/books', 'Books' ],
71
+ [ '/categories', 'Categories' ],
72
+ [ '/chapters', 'Chapters' ],
73
+ [ '/tags', 'Tags' ]
74
+ ]
75
+ end
76
+
77
+ get '/' do
78
+ @details = OpenStruct.new( attributes: {} )
79
+ slim 'h2 Main', layout: :layout
80
+ end
81
+
82
+ # List
83
+ get '/:model' do
84
+ mod = @models[params[:model].to_sym]
85
+ @model = mod.to_s.split( '::' ).last.gsub( /([A-Z]+)([A-Z][a-z])/, '\1_\2' ).gsub( /([a-z\d])([A-Z])/, '\1_\2' ).tr( '-', '_' ).downcase
86
+ @list = mod.all
87
+ slim "h2 #{params[:model]}", layout: :layout
88
+ end
89
+
90
+ # Create
91
+ post '/:model' do
92
+ mod = @models[params[:model].to_sym]
93
+ @model = mod.to_s.split( '::' ).last.gsub( /([A-Z]+)([A-Z][a-z])/, '\1_\2' ).gsub( /([a-z\d])([A-Z])/, '\1_\2' ).tr( '-', '_' ).downcase
94
+ mod.new( @model => params[@model] ).save
95
+ redirect to "/#{params[:model]}"
96
+ end
97
+
98
+ # Read
99
+ get '/:model/:id' do
100
+ mod = @models[params[:model].to_sym]
101
+ @details = mod.find( params[:id] )
102
+ @model = mod.to_s.split( '::' ).last.gsub( /([A-Z]+)([A-Z][a-z])/, '\1_\2' ).gsub( /([a-z\d])([A-Z])/, '\1_\2' ).tr( '-', '_' ).downcase
103
+ slim "h2 #{params[:model]}", layout: :layout
104
+ end
105
+
106
+ # Update
107
+ post '/:model/:id' do
108
+ mod = @models[params[:model].to_sym]
109
+ @details = mod.find( params[:id] )
110
+ @model = mod.to_s.split( '::' ).last.gsub( /([A-Z]+)([A-Z][a-z])/, '\1_\2' ).gsub( /([a-z\d])([A-Z])/, '\1_\2' ).tr( '-', '_' ).downcase
111
+ params[@model].each { |k, v| @details.send( "#{k}=", v ) }
112
+ @details.save
113
+ redirect to "/#{params[:model]}"
114
+ end
115
+
116
+ # Delete
117
+ get '/:model/:id/delete' do
118
+ @item = @models[params[:model].to_sym].find( params[:id] )
119
+ @item.destroy
120
+ redirect to "/#{params[:model]}"
121
+ end
122
+
123
+ run! if app_file == $PROGRAM_NAME # = $0 ## starts the server if executed directly by ruby
124
+ end
125
+ end
@@ -0,0 +1,9 @@
1
+ # config.ru (run with rackup)
2
+
3
+ # Launch with:
4
+ # rackup -o 0.0.0.0 -p 4567
5
+
6
+ require './app'
7
+
8
+ # run App
9
+ run ActiveResourceTest::App
@@ -0,0 +1,78 @@
1
+ doctype html
2
+ html
3
+ head
4
+ title Test
5
+ link rel='stylesheet' href='http://yui.yahooapis.com/pure/0.6.0/pure-min.css'
6
+ css:
7
+ a { color: #b00; text-decoration: none; }
8
+ body { padding: 0 15px; }
9
+ input[type='submit'] { margin-top: 15px; }
10
+ form { margin-top: 30px; }
11
+ hr { margin: 20px 0; }
12
+ legend { font-style: italic; font-weight: bold; }
13
+ table { font-size: 13px; }
14
+ body
15
+ == yield
16
+ - unless @links.nil?
17
+ / Menu
18
+ div
19
+ - @links.each do |link|
20
+ a.pure-button.pure-button-primary href="#{link[0]}" = link[1]
21
+ | &nbsp;
22
+ hr
23
+ - if !@list.nil? && @list.any?
24
+ / List
25
+ table.pure-table
26
+ thead
27
+ th
28
+ - @list.first.attributes.keys.each do |col|
29
+ th = col
30
+ tbody
31
+ - @list.each_with_index do |row, index|
32
+ tr
33
+ td
34
+ a href="#{request.path_info + '/' + row.id.to_s}"
35
+ = '#' + ( index + 1 ).to_s
36
+ - row.attributes.each do |cell|
37
+ - value = cell[1]
38
+ td
39
+ - if value.is_a? Array
40
+ = value.map( &:id ).join( ', ' )
41
+ - elsif value.class.ancestors.include? ActiveResource::Base
42
+ = value.name if value.attributes.has_key? :name
43
+ = value.title if value.attributes.has_key? :title
44
+ - else
45
+ = value
46
+ - if !@details.nil? && !@model.nil?
47
+ / Edit
48
+ form.pure-form.pure-form-stacked method='post' action=''
49
+ fieldset
50
+ legend = 'Edit ' + @model
51
+ table.pure-table
52
+ - @details.attributes.each do |key, value|
53
+ tr
54
+ td
55
+ b = key
56
+ td
57
+ - if value.is_a? Array
58
+ = value.map( &:id ).join( ', ' )
59
+ - elsif value.class.ancestors.include? ActiveResource::Base
60
+ = value.name if value.attributes.has_key? :name
61
+ = value.title if value.attributes.has_key? :title
62
+ - elsif key == 'id'
63
+ = value
64
+ - else
65
+ input type='text' name="#{@model}[#{key}]" value="#{value}"
66
+ input.pure-button.pure-button-success type='submit' value='update'
67
+ form.pure-form.pure-form-stacked method='delete' action='#{params[:id]}/delete'
68
+ input.pure-button.pure-button-success type='submit' value='delete'
69
+ - elsif !@model.nil?
70
+ / Form new
71
+ form.pure-form.pure-form-stacked method='post' action=''
72
+ fieldset
73
+ legend = 'Create ' + @model
74
+ - @list.first.attributes.keys.each do |col|
75
+ - if col != 'id'
76
+ label = col
77
+ input type='text' name="#{@model}[#{col}]" value=''
78
+ input.pure-button.pure-button-success type='submit' value='create'