vodka 0.1.0 → 0.1.2

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 (58) hide show
  1. data/.travis.yml +2 -0
  2. data/README.md +33 -10
  3. data/lib/party.rb +2 -1
  4. data/lib/vodka/client.rb +0 -2
  5. data/lib/vodka/client/middleware/signed_request.rb +1 -1
  6. data/lib/vodka/client/middleware/signed_response.rb +1 -1
  7. data/lib/vodka/configuration.rb +27 -12
  8. data/lib/vodka/server.rb +3 -0
  9. data/lib/vodka/server/controllers/vodka_controller.rb +1 -5
  10. data/lib/vodka/server/handlers/resource.rb +6 -2
  11. data/lib/vodka/server/handlers/response.rb +10 -6
  12. data/lib/vodka/server/handlers/scaffold.rb +5 -35
  13. data/lib/vodka/server/middleware/signed_request.rb +6 -4
  14. data/lib/vodka/server/plugins/presentable.rb +24 -9
  15. data/lib/vodka/server/presenters/vodka_presenter.rb +23 -0
  16. data/lib/vodka/server/railtie.rb +13 -0
  17. data/lib/vodka/server/relation.rb +95 -0
  18. data/lib/vodka/server/response.rb +18 -7
  19. data/lib/vodka/version.rb +1 -1
  20. data/script/dummy_console +6 -0
  21. data/script/setup_db +2 -2
  22. data/script/show_logs +1 -1
  23. data/script/spec +5 -9
  24. data/script/start_server +2 -2
  25. data/script/stop_server +1 -1
  26. data/spec/client/article.rb +2 -0
  27. data/spec/client/author.rb +3 -0
  28. data/spec/client/comment.rb +4 -0
  29. data/spec/dummy/Gemfile +6 -5
  30. data/spec/dummy/Gemfile.lock +19 -4
  31. data/spec/dummy/app/controllers/articles_controller.rb +5 -0
  32. data/spec/dummy/app/controllers/vodka/authors_controller.rb +4 -0
  33. data/spec/dummy/app/controllers/vodka/comments_controller.rb +4 -0
  34. data/spec/dummy/app/models/article.rb +9 -2
  35. data/spec/dummy/app/models/author.rb +5 -0
  36. data/spec/dummy/app/models/comment.rb +12 -0
  37. data/spec/dummy/app/models/like.rb +9 -0
  38. data/spec/dummy/app/presenters/article_presenter.rb +9 -0
  39. data/spec/dummy/app/presenters/author_custom_presenter.rb +5 -0
  40. data/spec/dummy/app/presenters/comment_presenter.rb +13 -0
  41. data/spec/dummy/config/database.yml +3 -3
  42. data/spec/dummy/config/initializers/mongo_mapper_connection.rb +4 -0
  43. data/spec/dummy/config/initializers/vodka_setup.rb +1 -0
  44. data/spec/dummy/config/mongoid.yml +32 -0
  45. data/spec/dummy/config/routes.rb +4 -0
  46. data/spec/dummy/config/thin.yml +1 -1
  47. data/spec/dummy/db/migrate/20130217185353_create_articles.rb +1 -0
  48. data/spec/dummy/db/schema.rb +1 -0
  49. data/spec/dummy/db/seeds.rb +18 -1
  50. data/spec/her/extensions/paginated/paginate_spec.rb +32 -0
  51. data/spec/middleware/response_locale_spec.rb +2 -0
  52. data/spec/requests/relations_spec.rb +9 -0
  53. data/spec/spec_helper.rb +2 -1
  54. data/vodka.gemspec +1 -1
  55. metadata +23 -8
  56. data/lib/vodka/her/extensions/extended_orm.rb +0 -92
  57. data/lib/vodka/her/extensions/will_paginate.rb +0 -32
  58. data/spec/her/extensions/will_paginate/paginate_spec.rb +0 -16
@@ -6,6 +6,19 @@ module Vodka
6
6
  initializer 'vodka.inject_middleware' do |app|
7
7
  app.config.middleware.use 'Vodka::Server::Middleware::SignedRequest'
8
8
  end
9
+
10
+ initializer 'vodka.inject_presenter' do |app|
11
+ if defined?(ActiveRecord)
12
+ ActiveRecord::Base.send(:include, Vodka::Server::Plugins::Presentable)
13
+ end
14
+ if defined?(MongoMapper)
15
+ MongoMapper::Document.send(:include, Vodka::Server::Plugins::Presentable)
16
+ MongoMapper::EmbeddedDocument.send(:include, Vodka::Server::Plugins::Presentable)
17
+ end
18
+ if defined?(Mongoid)
19
+ Mongoid::Document.send(:include, Vodka::Server::Plugins::Presentable)
20
+ end
21
+ end
9
22
  end
10
23
  end
11
24
  end
@@ -0,0 +1,95 @@
1
+ module Vodka
2
+ module Server
3
+ class Relation
4
+ attr_accessor :klass, :relation, :params, :data, :metadata
5
+
6
+ def initialize(klass, params)
7
+ @klass = klass
8
+ @relation = klass
9
+ @params = params
10
+ @data = []
11
+ @metadata = {}
12
+
13
+ convert!
14
+ end
15
+
16
+ private
17
+
18
+ def convert!
19
+ apply_where_conditions!
20
+ apply_group_conditions!
21
+ apply_having_conditions!
22
+ apply_order_conditions!
23
+ apply_limit_condition!
24
+ apply_offset_condition!
25
+ apply_pagination!
26
+
27
+ if params.has_key?(:her_special_count)
28
+ @data = [relation.count]
29
+ elsif relation == klass
30
+ @data = relation.all
31
+ elsif relation.respond_to?(:to_a)
32
+ @data = relation.to_a
33
+ end
34
+ end
35
+
36
+ def apply!(method, *args)
37
+ @relation = @relation.send(method, *args) if @relation.respond_to?(method)
38
+ end
39
+
40
+ def apply_where_conditions!
41
+ return unless params.has_key?(:her_special_where)
42
+
43
+ MultiJson.load(params[:her_special_where]).each do |condition|
44
+ condition.is_a?(Hash) ? apply!(:where, condition) : apply!(:where, *condition)
45
+ end
46
+ end
47
+
48
+ def apply_group_conditions!
49
+ return unless params.has_key?(:her_special_group)
50
+
51
+ MultiJson.load(params[:her_special_group]).each do |condition|
52
+ if relation.respond_to?(:group)
53
+ apply!(:group, condition)
54
+ elsif relation.respond_to?(:group_by)
55
+ apply!(:group_by, condition)
56
+ end
57
+ end
58
+ end
59
+
60
+ def apply_having_conditions!
61
+ return unless params.has_key?(:her_special_having)
62
+
63
+ MultiJson.load(params[:her_special_having]).each do |condition|
64
+ apply!(:having, condition)
65
+ end
66
+ end
67
+
68
+ def apply_order_conditions!
69
+ return unless params.has_key?(:her_special_order)
70
+
71
+ MultiJson.load(params[:her_special_order]).each do |condition|
72
+ apply!(:order, condition)
73
+ end
74
+ end
75
+
76
+ def apply_limit_condition!
77
+ apply!(:limit, params[:her_special_limit].to_i) if params.has_key?(:her_special_limit)
78
+ end
79
+
80
+ def apply_offset_condition!
81
+ apply!(:offset, params[:her_special_offset].to_i) if params.has_key?(:her_special_offset)
82
+ end
83
+
84
+ def apply_pagination!
85
+ return unless params.has_key?(:her_special_paginate)
86
+
87
+ per_page = params[:her_special_limit].to_i
88
+ current_page = params[:her_special_offset].to_i / per_page + 1
89
+ total_entries = relation.count
90
+
91
+ @metadata = { current_page: current_page, per_page: per_page, total_entries: total_entries }
92
+ end
93
+ end
94
+ end
95
+ end
@@ -1,7 +1,7 @@
1
1
  module Vodka
2
2
  module Server
3
3
  class Response
4
- attr_accessor :id, :code, :success, :data, :metadata, :errors
4
+ attr_accessor :id, :code, :success, :data, :presenter, :metadata, :errors
5
5
 
6
6
  def initialize
7
7
  @code = 200
@@ -13,25 +13,36 @@ module Vodka
13
13
  metadata[:vodka_action_success] = success unless success.nil?
14
14
 
15
15
  if data.nil?
16
- presented_data = nil
16
+ presented_data = {}
17
17
  errors_to_return = errors
18
18
  elsif data.is_a?(Array)
19
- presented_data = data.map(&:present_vodka)
19
+ presented_data = data.map{ |item| present(item) }
20
20
  errors_to_return = errors
21
21
  else
22
- presented_data = data.present_vodka
22
+ presented_data = present(data)
23
23
  errors_to_return = presented_data.delete(:errors)
24
24
  end
25
25
 
26
- MultiJson.dump(
26
+ response = {
27
27
  data: presented_data,
28
28
  metadata: metadata,
29
29
  errors: errors_to_return
30
- )
30
+ }
31
+ # ap response if Rails.env.development? && defined?(AwesomePrint)
32
+ MultiJson.dump(response)
33
+ end
34
+
35
+ def present(item)
36
+ return item if item.is_a?(Hash)
37
+ if presenter.nil?
38
+ item.try(:present)
39
+ else
40
+ presenter.new(item).present
41
+ end
31
42
  end
32
43
 
33
44
  def signature
34
- Digest::SHA512.hexdigest([id, Vodka::Server.config.response_secret].join)
45
+ Vodka::Server.config.digest.hexdigest([id, Vodka::Server.config.response_secret].join)
35
46
  end
36
47
  end
37
48
  end
@@ -1,3 +1,3 @@
1
1
  module Vodka
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.2'
3
3
  end
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+ dummy_path="$(pwd)/spec/dummy"
3
+ BUNDLE_PATH=$dummy_path/.bundle
4
+ BUNDLE_GEMFILE=$dummy_path/Gemfile
5
+ RAILS_ENV=development
6
+ cd $dummy_path && bundle exec rails console
@@ -2,6 +2,6 @@
2
2
  dummy_path="$(pwd)/spec/dummy"
3
3
  BUNDLE_PATH=$dummy_path/.bundle
4
4
  BUNDLE_GEMFILE=$dummy_path/Gemfile
5
- RAILS_ENV=test
5
+ RAILS_ENV=development
6
6
  cd $dummy_path && bundle exec rake db:migrate 2>&1 > $dummy_path/log/setup_db.log
7
- cd $dummy_path && bundle exec rake db:test:prepare 2>&1 > $dummy_path/log/setup_db.log
7
+ cd $dummy_path && bundle exec rake db:seed 2>&1 >> $dummy_path/log/setup_db.log
@@ -18,5 +18,5 @@ cat $dummy_path/log/thin.3000.log
18
18
  echo ''
19
19
 
20
20
  echo 'Dummy log:'
21
- cat $dummy_path/log/test.log
21
+ cat $dummy_path/log/development.log
22
22
  echo ''
@@ -1,14 +1,10 @@
1
1
  #!/bin/bash
2
2
 
3
- cd spec/dummy
4
- rm -f log/*
5
- bundle install --path .bundle 2>&1 > log/bundler.log
6
- RAILS_ENV=test bundle exec rake db:reset 2>&1 > log/setup_db.log
7
- RAILS_ENV=test bundle exec thin start -C config/thin.yml 2>&1 > log/thin_start.log
8
- cd ../..
3
+ rm -f spec/dummy/log/*
4
+ ./script/bundle_dummy
5
+ ./script/setup_db
6
+ ./script/start_server
9
7
  bundle exec rspec
10
8
  code=$?
11
- cd spec/dummy
12
- RAILS_ENV=test bundle exec thin stop -C config/thin.yml 2>&1 > log/thin_stop.log
13
- cd ../..
9
+ ./script/stop_server
14
10
  exit $code
@@ -2,5 +2,5 @@
2
2
  dummy_path="$(pwd)/spec/dummy"
3
3
  BUNDLE_PATH=$dummy_path/.bundle
4
4
  BUNDLE_GEMFILE=$dummy_path/Gemfile
5
- RAILS_ENV=test
6
- cd $dummy_path && bundle exec thin start -C $dummy_path/config/thin.yml 2>&1 > $dummy_path/log/thin_start.log
5
+ RAILS_ENV=development
6
+ cd $dummy_path && bundle exec thin start -C $dummy_path/config/thin.yml # 2>&1 > $dummy_path/log/thin_start.log
@@ -2,5 +2,5 @@
2
2
  dummy_path="$(pwd)/spec/dummy"
3
3
  BUNDLE_PATH=$dummy_path/.bundle
4
4
  BUNDLE_GEMFILE=$dummy_path/Gemfile
5
- RAILS_ENV=test
5
+ RAILS_ENV=development
6
6
  cd $dummy_path && bundle exec thin stop -C $dummy_path/config/thin.yml 2>&1 > /dev/null
@@ -1,4 +1,6 @@
1
1
  class Article
2
2
  include Her::Model
3
3
  custom_get :hello
4
+ has_many :comments
5
+ belongs_to :author
4
6
  end
@@ -0,0 +1,3 @@
1
+ class Author
2
+ include Her::Model
3
+ end
@@ -0,0 +1,4 @@
1
+ class Comment
2
+ include Her::Model
3
+ belongs_to :author
4
+ end
@@ -1,9 +1,10 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'rails', '~> 3.2.12'
4
- gem 'will_paginate', '~> 3.0.4'
5
- gem 'sqlite3', '~> 1.3.7'
6
- gem 'thin', '~> 1.5.0'
7
- gem 'multi_json', '~> 1.6.1'
3
+ gem 'rails', '~> 3.2.12'
4
+ gem 'thin', '~> 1.5.0'
5
+
6
+ gem 'sqlite3', '~> 1.3.7'
7
+ gem 'mongo_mapper', '~> 0.12.0'
8
+ gem 'mongoid', '~> 3.1.2'
8
9
 
9
10
  gem 'vodka', path: '../..', require: 'vodka/server'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- vodka (0.0.1)
4
+ vodka (0.1.0)
5
5
  her (~> 0.4)
6
6
  multi_json (~> 1.6.1)
7
7
 
@@ -36,6 +36,7 @@ GEM
36
36
  i18n (~> 0.6)
37
37
  multi_json (~> 1.0)
38
38
  arel (3.0.2)
39
+ bson (1.8.2)
39
40
  builder (3.0.4)
40
41
  daemons (1.1.9)
41
42
  erubis (2.7.0)
@@ -55,8 +56,23 @@ GEM
55
56
  mime-types (~> 1.16)
56
57
  treetop (~> 1.4.8)
57
58
  mime-types (1.21)
59
+ mongo (1.8.2)
60
+ bson (~> 1.8.2)
61
+ mongo_mapper (0.12.0)
62
+ activemodel (~> 3.0)
63
+ activesupport (~> 3.0)
64
+ plucky (~> 0.5.2)
65
+ mongoid (3.1.2)
66
+ activemodel (~> 3.2)
67
+ moped (~> 1.4.2)
68
+ origin (~> 1.0)
69
+ tzinfo (~> 0.3.22)
70
+ moped (1.4.2)
58
71
  multi_json (1.6.1)
59
72
  multipart-post (1.1.5)
73
+ origin (1.0.11)
74
+ plucky (0.5.2)
75
+ mongo (~> 1.5)
60
76
  polyglot (0.3.3)
61
77
  rack (1.4.5)
62
78
  rack-cache (1.2)
@@ -99,15 +115,14 @@ GEM
99
115
  polyglot
100
116
  polyglot (>= 0.3.1)
101
117
  tzinfo (0.3.35)
102
- will_paginate (3.0.4)
103
118
 
104
119
  PLATFORMS
105
120
  ruby
106
121
 
107
122
  DEPENDENCIES
108
- multi_json (~> 1.6.1)
123
+ mongo_mapper (~> 0.12.0)
124
+ mongoid (~> 3.1.2)
109
125
  rails (~> 3.2.12)
110
126
  sqlite3 (~> 1.3.7)
111
127
  thin (~> 1.5.0)
112
128
  vodka!
113
- will_paginate (~> 3.0.4)
@@ -0,0 +1,5 @@
1
+ class ArticlesController < ApplicationController
2
+ def index
3
+ render json: Article.all
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module Vodka
2
+ class AuthorsController < VodkaController
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Vodka
2
+ class CommentsController < VodkaController
3
+ end
4
+ end
@@ -1,10 +1,17 @@
1
1
  class Article < ActiveRecord::Base
2
- present_with :id, :title
3
- attr_accessible :title
2
+ attr_accessible :title, :author_id
4
3
  validates_presence_of :title
5
4
  before_destroy :ensure_article_in_not_special
6
5
 
7
6
  def ensure_article_in_not_special
8
7
  return false if title == 'special'
9
8
  end
9
+
10
+ def author
11
+ Author.find(author_id) if author_id?
12
+ end
13
+
14
+ def comments
15
+ Comment.where(article_id: id)
16
+ end
10
17
  end
@@ -0,0 +1,5 @@
1
+ class Author
2
+ include Mongoid::Document
3
+ field :name, type: String
4
+ present_with AuthorCustomPresenter
5
+ end
@@ -0,0 +1,12 @@
1
+ class Comment
2
+ include MongoMapper::Document
3
+ key :article_id, Integer
4
+ key :body, String
5
+ key :author_id, String
6
+
7
+ many :likes
8
+
9
+ def author
10
+ Author.find(author_id)
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ class Like
2
+ include MongoMapper::EmbeddedDocument
3
+ key :author_id, String
4
+ embedded_in :comment
5
+
6
+ def author
7
+ Author.find(author_id)
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class ArticlePresenter < VodkaPresenter
2
+ def present
3
+ json(
4
+ id: resource.id,
5
+ title: resource.title,
6
+ author: resource.author.try(:present)
7
+ )
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ class AuthorCustomPresenter < VodkaPresenter
2
+ def present
3
+ json(id: resource.id, name: resource.name)
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ class CommentPresenter < VodkaPresenter
2
+ def present
3
+ json(
4
+ body: resource.body,
5
+ author: resource.author.try(:present),
6
+ likes: likes
7
+ )
8
+ end
9
+
10
+ def likes
11
+ resource.likes.map{ |like| like.author.try(:present) }
12
+ end
13
+ end
@@ -1,17 +1,17 @@
1
1
  development:
2
2
  adapter: sqlite3
3
- database: db/test.sqlite3
3
+ database: db/development.sqlite3
4
4
  pool: 5
5
5
  timeout: 5000
6
6
 
7
7
  test:
8
8
  adapter: sqlite3
9
- database: db/test.sqlite3
9
+ database: db/development.sqlite3
10
10
  pool: 5
11
11
  timeout: 5000
12
12
 
13
13
  production:
14
14
  adapter: sqlite3
15
- database: db/test.sqlite3
15
+ database: db/development.sqlite3
16
16
  pool: 5
17
17
  timeout: 5000