at_your_service 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +149 -0
  7. data/Rakefile +2 -0
  8. data/at_your_service.gemspec +26 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/lib/at_your_service.rb +9 -0
  12. data/lib/at_your_service/error.rb +23 -0
  13. data/lib/at_your_service/service.rb +20 -0
  14. data/lib/at_your_service/success.rb +17 -0
  15. data/lib/at_your_service/version.rb +3 -0
  16. data/rails_test/rails_app/.gitignore +21 -0
  17. data/rails_test/rails_app/.rspec +2 -0
  18. data/rails_test/rails_app/Gemfile +28 -0
  19. data/rails_test/rails_app/Gemfile.lock +216 -0
  20. data/rails_test/rails_app/README.md +24 -0
  21. data/rails_test/rails_app/Rakefile +6 -0
  22. data/rails_test/rails_app/app/assets/config/manifest.js +3 -0
  23. data/rails_test/rails_app/app/assets/images/.keep +0 -0
  24. data/rails_test/rails_app/app/assets/javascripts/application.js +16 -0
  25. data/rails_test/rails_app/app/assets/javascripts/cable.js +13 -0
  26. data/rails_test/rails_app/app/assets/javascripts/channels/.keep +0 -0
  27. data/rails_test/rails_app/app/assets/stylesheets/application.css +15 -0
  28. data/rails_test/rails_app/app/channels/application_cable/channel.rb +4 -0
  29. data/rails_test/rails_app/app/channels/application_cable/connection.rb +4 -0
  30. data/rails_test/rails_app/app/controllers/application_controller.rb +9 -0
  31. data/rails_test/rails_app/app/controllers/concerns/.keep +0 -0
  32. data/rails_test/rails_app/app/helpers/application_helper.rb +2 -0
  33. data/rails_test/rails_app/app/jobs/application_job.rb +2 -0
  34. data/rails_test/rails_app/app/mailers/application_mailer.rb +4 -0
  35. data/rails_test/rails_app/app/models/application_record.rb +3 -0
  36. data/rails_test/rails_app/app/models/concerns/.keep +0 -0
  37. data/rails_test/rails_app/app/services/test_non_strict_service.rb +16 -0
  38. data/rails_test/rails_app/app/services/test_strict_service.rb +16 -0
  39. data/rails_test/rails_app/app/views/layouts/application.html.erb +14 -0
  40. data/rails_test/rails_app/app/views/layouts/mailer.html.erb +13 -0
  41. data/rails_test/rails_app/app/views/layouts/mailer.text.erb +1 -0
  42. data/rails_test/rails_app/bin/bundle +3 -0
  43. data/rails_test/rails_app/bin/rails +9 -0
  44. data/rails_test/rails_app/bin/rake +9 -0
  45. data/rails_test/rails_app/bin/setup +34 -0
  46. data/rails_test/rails_app/bin/spring +16 -0
  47. data/rails_test/rails_app/bin/update +29 -0
  48. data/rails_test/rails_app/config.ru +5 -0
  49. data/rails_test/rails_app/config/application.rb +16 -0
  50. data/rails_test/rails_app/config/boot.rb +3 -0
  51. data/rails_test/rails_app/config/cable.yml +9 -0
  52. data/rails_test/rails_app/config/database.yml +25 -0
  53. data/rails_test/rails_app/config/environment.rb +5 -0
  54. data/rails_test/rails_app/config/environments/development.rb +54 -0
  55. data/rails_test/rails_app/config/environments/production.rb +86 -0
  56. data/rails_test/rails_app/config/environments/test.rb +42 -0
  57. data/rails_test/rails_app/config/initializers/application_controller_renderer.rb +6 -0
  58. data/rails_test/rails_app/config/initializers/assets.rb +11 -0
  59. data/rails_test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  60. data/rails_test/rails_app/config/initializers/cookies_serializer.rb +5 -0
  61. data/rails_test/rails_app/config/initializers/filter_parameter_logging.rb +4 -0
  62. data/rails_test/rails_app/config/initializers/inflections.rb +16 -0
  63. data/rails_test/rails_app/config/initializers/mime_types.rb +4 -0
  64. data/rails_test/rails_app/config/initializers/new_framework_defaults.rb +24 -0
  65. data/rails_test/rails_app/config/initializers/session_store.rb +3 -0
  66. data/rails_test/rails_app/config/initializers/wrap_parameters.rb +14 -0
  67. data/rails_test/rails_app/config/locales/en.yml +23 -0
  68. data/rails_test/rails_app/config/puma.rb +47 -0
  69. data/rails_test/rails_app/config/routes.rb +5 -0
  70. data/rails_test/rails_app/config/secrets.yml +22 -0
  71. data/rails_test/rails_app/config/spring.rb +6 -0
  72. data/rails_test/rails_app/db/seeds.rb +7 -0
  73. data/rails_test/rails_app/lib/assets/.keep +0 -0
  74. data/rails_test/rails_app/lib/tasks/.keep +0 -0
  75. data/rails_test/rails_app/log/.keep +0 -0
  76. data/rails_test/rails_app/public/404.html +67 -0
  77. data/rails_test/rails_app/public/422.html +67 -0
  78. data/rails_test/rails_app/public/500.html +66 -0
  79. data/rails_test/rails_app/public/apple-touch-icon-precomposed.png +0 -0
  80. data/rails_test/rails_app/public/apple-touch-icon.png +0 -0
  81. data/rails_test/rails_app/public/favicon.ico +0 -0
  82. data/rails_test/rails_app/public/robots.txt +5 -0
  83. data/rails_test/rails_app/spec/rails_helper.rb +57 -0
  84. data/rails_test/rails_app/spec/services/test_non_strict_service_spec.rb +18 -0
  85. data/rails_test/rails_app/spec/services/test_strict_services_spec.rb +18 -0
  86. data/rails_test/rails_app/spec/spec_helper.rb +99 -0
  87. data/rails_test/rails_app/tmp/.keep +0 -0
  88. data/rails_test/rails_app/vendor/assets/javascripts/.keep +0 -0
  89. data/rails_test/rails_app/vendor/assets/stylesheets/.keep +0 -0
  90. metadata +190 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1c946ae28705743ef7bca51989a8ec28dbb2fcb9
4
+ data.tar.gz: 29d00ed7a85d610cfdd1263e2e0f45bcb87222b1
5
+ SHA512:
6
+ metadata.gz: 3e00b9c60049be3793183920934d3197516a9c0521f7a74c076b838332123e125e1637c8e002fe9cc58420c17364ffb02fd11ab15609d7b717d3979a626acb26
7
+ data.tar.gz: 48e45e03159b0edcc2a051fa947114a54de32cf7ca15a4c8a5d2711e09603714c892a9339a8eba5dbce384fa5ecf221d98047f9f71fc077e41a3c8b85894229b
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.swp
11
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in at_your_service.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Ben Gelsey
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,149 @@
1
+ # At Your Service
2
+ ##### Service Objects made easy (& works great w/ Rails)
3
+
4
+ Model / View / Controller isn't enough for today's complex web applications. Encapsulate your business logic in Service objects so that when you write a piece of business logic, you only write it once.
5
+
6
+ Inspiration & How to Use Service Objects:
7
+
8
+ [Gourmet Service Objects --- by Brewhouse](http://brewhouse.io/blog/2014/04/30/gourmet-service-objects.html)
9
+
10
+ [Using Services to Keep Your Rails Controllers Clean and DRY --- by Engine Yard](https://blog.engineyard.com/2014/keeping-your-rails-controllers-dry-with-services)
11
+
12
+ [7 Patterns to Refactor Fat ActiveRecord Models --- by Code Climate (see #2)](http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/)
13
+
14
+ [Service objects in Rails will help you design clean and maintainable code. Here's how. --- via netguru](https://www.netguru.co/blog/service-objects-in-rails-will-help)
15
+
16
+ ## Installation
17
+
18
+ Add this line to your application's Gemfile:
19
+
20
+ ```ruby
21
+ gem 'at_your_service'
22
+ ```
23
+
24
+ And then execute:
25
+
26
+ $ bundle install
27
+
28
+ Or install it yourself as:
29
+
30
+ $ gem install at_your_service
31
+
32
+ ## Example
33
+
34
+ Adding a user's Credit Card is a common piece of business logic. The below example uses [Stripe](https://stripe.com/) to do so. By having this logic in a Service, whether it is an admin manually adding a new Credit Card for a User OR the User adding it themselves in the checkout flow, the logic will be exactly the same. Though the Renter object is the primary Active Record model involved, having this method as part of the Renter model would lead to that class being massive and unwieldy. It is much better as a standalone service, as shown below.
35
+
36
+ ```ruby
37
+ class AddCard
38
+ include AtYourService.with(strict: true)
39
+
40
+ attribute :renter, Renter
41
+ attribute :token, String
42
+ attribute :agent_name, String
43
+
44
+ UPDATE_RENTER_CUSTOMER_ID_ERROR = 'Could not associate Stripe data with Renter'
45
+
46
+ def call
47
+ begin
48
+ customer = nil
49
+ cards = []
50
+ if renter.stripe_customer_id
51
+ # Add card to customer
52
+ customer = Stripe::Customer.retrieve(renter.stripe_customer_id)
53
+ cards << customer.sources.create(source: token)
54
+ else
55
+ # Create new customer w/ card
56
+ customer = Stripe::Customer.create(
57
+ source: token,
58
+ email: renter.email,
59
+ description: "#{renter.full_name} - ##{renter.id} - created by #{agent_name}"
60
+ )
61
+ unless customer && renter.update(stripe_customer_id: customer.id)
62
+ Rails.logger.error "New Stripe Customer #{customer.inspect} could not be associated with Renter #{renter.inspect}"
63
+ return Error.new(UPDATE_RENTER_CUSTOMER_ID_ERROR)
64
+ end
65
+ end
66
+ cards += customer.sources.data
67
+ return Success.new(renter: ::Web::RenterStripeDecorator.new(renter), cards: cards)
68
+ rescue Stripe::CardError => e
69
+ return Error.new(e.json_body[:error][:message])
70
+ end
71
+ end
72
+ end
73
+ ```
74
+
75
+ ## Setup
76
+
77
+ 1. create directory app/services.
78
+ 2. Add `config.autoload_paths += Dir["#{config.root}/app/services"]` to config/application.rb.
79
+ 3. That's it! You are now ready to write your first Service
80
+
81
+
82
+ ## How to Write a Service
83
+
84
+ 1. Create a class in the `app/services` directory
85
+ 2. Include AtYourService
86
+ 3. Define Attributes (strict or lenient) via the [Virtus Gem](https://github.com/solnic/virtus)
87
+ 4. Create the `call` method
88
+ 5. Write your Business Logic (+ private helper methods)
89
+ 6. Return a `Success` or `Error` object
90
+
91
+ ##### Create a class in the `app/services` directory
92
+ Name your class with what the service does. If it's adding a credit card, call it `AddCard`. If it's generating a quote, call it `GenerateQuote`, etc.
93
+
94
+ ##### Include AtYourService
95
+ Include the AtYourService module via `include AtYourService`
96
+
97
+ ##### Define Attributes
98
+ With attributes, we clearly define the data that Service needs including the types. With [Strict Coercion mode](https://github.com/solnic/virtus#strict-coercion-mode) from Virtus, an error will be thrown if the inputted arguments cannot be coerced into the desired type (so no nils as arguments). By default, strict coercion mode is off and you can have nil attributes. To use strict coercion mode, modify your AtYourService include to be `include AtYourService.with(strict: true)`
99
+
100
+ ##### Create the `call` Method
101
+ At Your Service flavored service objects always define `call`. This prevents the awkwardness of having to name both your service class and it's method (stuff like `AddCard.add_card`). Now just name your class for what the service does (AddCard, SendInvite, MarkActiveReservation, ReturnProduct etc.) and then you always know you call it with `.call`.
102
+
103
+ ##### Write your Business Logic
104
+ Inside `call`, define your business logic. Reference attributes by name, so `attribute :user` would just be `user` inside `call`. Go wild here, Service objects are meant to house the complex business logic of your application. For convenience, you can define private helper methods below call like usual.
105
+
106
+ ##### Return a `Success` or `Error` object
107
+ Again, with At Your Service we are all about consistency. Every Service should return either a `Success` or `Error` object and pass into it the appropriate data (for Success) or error messages (for Error). Take a look at the source of these two classes. They're very simple. For convenience, `Error.new` accepts either a string or array of string error messages. With Success you can pass in any data you want, but usually a hash `{user: user, order: order}` works best.
108
+
109
+ ## Rails API Example
110
+ Services are a great way to shrink your Rails controllers. Rather than having messy business logic in your controller, just offload it to a reusable Service that can be called across your codebase. I have many 2-line controller methods like so:
111
+
112
+ ```ruby
113
+ class OrderWizardController < ApplicationController
114
+ def generate_quote
115
+ result = GenerateQuote.call(params)
116
+ render json: result.display
117
+ end
118
+
119
+ def accept_quote
120
+ result = AcceptQuote.call(params)
121
+ render json: result.display
122
+ end
123
+
124
+ def remove_line_item
125
+ result = RemoveLineItem.call(params)
126
+ render json: result.display
127
+ end
128
+ # ... etc ...
129
+ end
130
+ ```
131
+
132
+ ## Questions?
133
+ At Your Service is a new gem. If any of the above documentation is confusing, unclear or insufficient please let me know! I am always available via email at ben@bengelsey.com to help you out :)
134
+
135
+ ## Contributing to At Your Service
136
+
137
+ #### Running the Tests
138
+ $ rspec
139
+ #### Running the Rails Tests
140
+ $ cd rails_test/rails_app/
141
+
142
+ $ rspec
143
+
144
+ PRs and Issues are always welcome!
145
+
146
+ ## License
147
+
148
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
149
+
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -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 'at_your_service/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "at_your_service"
8
+ spec.version = AtYourService::VERSION
9
+ spec.authors = ["Ben Gelsey"]
10
+ spec.email = ["ben@bengelsey.com"]
11
+
12
+ spec.summary = %q{At Your Service --- Service Objects made easy (& works great w/ Rails)}
13
+ spec.description = %q{Model / View / Controller isn't enough for today's complex web applications. Encapsulate your business logic in Service objects so that when you write a piece of business logic, you only write it once.}
14
+ spec.homepage = "https://github.com/theunixbeard/at_your_service"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.12"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rspec", "~> 3.5"
25
+ spec.add_dependency "virtus", "~> 1.0"
26
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "at_your_service"
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
@@ -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
@@ -0,0 +1,9 @@
1
+ require "at_your_service/version"
2
+ require "at_your_service/service"
3
+ require "at_your_service/error"
4
+ require "at_your_service/success"
5
+
6
+
7
+ module AtYourService
8
+ # Your code goes here...
9
+ end
@@ -0,0 +1,23 @@
1
+ class Error
2
+ attr_reader :errors
3
+ # Pass 1 string or array of strings
4
+ def initialize(errors = nil)
5
+ errors = [] unless errors
6
+ @errors = [errors].flatten # handle array or string
7
+ end
8
+
9
+ def error_message
10
+ errors[0]
11
+ end
12
+
13
+ def success?
14
+ false
15
+ end
16
+
17
+ def display
18
+ {
19
+ success: false,
20
+ errors: @errors
21
+ }
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ module AtYourService
2
+ extend ActiveSupport::Concern
3
+
4
+ def self.with(options = {})
5
+ @@strict = options.fetch(:strict, false)
6
+ return self
7
+ end
8
+
9
+ included do
10
+ if @@strict
11
+ include Virtus.model(strict: true)
12
+ else
13
+ include Virtus.model
14
+ end
15
+
16
+ def self.call(*args)
17
+ new(*args).call
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ class Success
2
+ attr_reader :data
3
+ def initialize(data)
4
+ @data = data
5
+ end
6
+
7
+ def success?
8
+ true
9
+ end
10
+
11
+ def display
12
+ {
13
+ success: true,
14
+ data: @data
15
+ }
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module AtYourService
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,21 @@
1
+ # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile '~/.gitignore_global'
6
+
7
+ # Ignore bundler config.
8
+ /.bundle
9
+
10
+ # Ignore the default SQLite database.
11
+ /db/*.sqlite3
12
+ /db/*.sqlite3-journal
13
+
14
+ # Ignore all logfiles and tempfiles.
15
+ /log/*
16
+ /tmp/*
17
+ !/log/.keep
18
+ !/tmp/.keep
19
+
20
+ # Ignore Byebug command history file.
21
+ .byebug_history
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,28 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails', '~> 5.0.0', '>= 5.0.0.1'
4
+ gem 'sqlite3'
5
+ gem 'puma', '~> 3.0'
6
+ gem 'sass-rails', '~> 5.0'
7
+ gem 'uglifier', '>= 1.3.0'
8
+ gem 'coffee-rails', '~> 4.2'
9
+ gem 'jquery-rails'
10
+ gem 'turbolinks', '~> 5'
11
+ gem 'jbuilder', '~> 2.5'
12
+ gem 'virtus'
13
+ gem 'rspec-rails'
14
+ gem 'at_your_service', :path => '../../../at_your_service'
15
+
16
+ group :development, :test do
17
+ gem 'byebug', platform: :mri
18
+ end
19
+
20
+ group :development do
21
+ gem 'web-console'
22
+ gem 'listen', '~> 3.0.5'
23
+ gem 'spring'
24
+ gem 'spring-watcher-listen', '~> 2.0.0'
25
+ end
26
+
27
+ # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
28
+ gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
@@ -0,0 +1,216 @@
1
+ PATH
2
+ remote: ../../../at_your_service
3
+ specs:
4
+ at_your_service (0.1.0)
5
+ virtus
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actioncable (5.0.0.1)
11
+ actionpack (= 5.0.0.1)
12
+ nio4r (~> 1.2)
13
+ websocket-driver (~> 0.6.1)
14
+ actionmailer (5.0.0.1)
15
+ actionpack (= 5.0.0.1)
16
+ actionview (= 5.0.0.1)
17
+ activejob (= 5.0.0.1)
18
+ mail (~> 2.5, >= 2.5.4)
19
+ rails-dom-testing (~> 2.0)
20
+ actionpack (5.0.0.1)
21
+ actionview (= 5.0.0.1)
22
+ activesupport (= 5.0.0.1)
23
+ rack (~> 2.0)
24
+ rack-test (~> 0.6.3)
25
+ rails-dom-testing (~> 2.0)
26
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
27
+ actionview (5.0.0.1)
28
+ activesupport (= 5.0.0.1)
29
+ builder (~> 3.1)
30
+ erubis (~> 2.7.0)
31
+ rails-dom-testing (~> 2.0)
32
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
33
+ activejob (5.0.0.1)
34
+ activesupport (= 5.0.0.1)
35
+ globalid (>= 0.3.6)
36
+ activemodel (5.0.0.1)
37
+ activesupport (= 5.0.0.1)
38
+ activerecord (5.0.0.1)
39
+ activemodel (= 5.0.0.1)
40
+ activesupport (= 5.0.0.1)
41
+ arel (~> 7.0)
42
+ activesupport (5.0.0.1)
43
+ concurrent-ruby (~> 1.0, >= 1.0.2)
44
+ i18n (~> 0.7)
45
+ minitest (~> 5.1)
46
+ tzinfo (~> 1.1)
47
+ arel (7.1.4)
48
+ axiom-types (0.1.1)
49
+ descendants_tracker (~> 0.0.4)
50
+ ice_nine (~> 0.11.0)
51
+ thread_safe (~> 0.3, >= 0.3.1)
52
+ builder (3.2.2)
53
+ byebug (9.0.6)
54
+ coercible (1.0.0)
55
+ descendants_tracker (~> 0.0.1)
56
+ coffee-rails (4.2.1)
57
+ coffee-script (>= 2.2.0)
58
+ railties (>= 4.0.0, < 5.2.x)
59
+ coffee-script (2.4.1)
60
+ coffee-script-source
61
+ execjs
62
+ coffee-script-source (1.11.1)
63
+ concurrent-ruby (1.0.2)
64
+ debug_inspector (0.0.2)
65
+ descendants_tracker (0.0.4)
66
+ thread_safe (~> 0.3, >= 0.3.1)
67
+ diff-lcs (1.2.5)
68
+ equalizer (0.0.11)
69
+ erubis (2.7.0)
70
+ execjs (2.7.0)
71
+ ffi (1.9.14)
72
+ globalid (0.3.7)
73
+ activesupport (>= 4.1.0)
74
+ i18n (0.7.0)
75
+ ice_nine (0.11.2)
76
+ jbuilder (2.6.1)
77
+ activesupport (>= 3.0.0, < 5.1)
78
+ multi_json (~> 1.2)
79
+ jquery-rails (4.2.1)
80
+ rails-dom-testing (>= 1, < 3)
81
+ railties (>= 4.2.0)
82
+ thor (>= 0.14, < 2.0)
83
+ listen (3.0.8)
84
+ rb-fsevent (~> 0.9, >= 0.9.4)
85
+ rb-inotify (~> 0.9, >= 0.9.7)
86
+ loofah (2.0.3)
87
+ nokogiri (>= 1.5.9)
88
+ mail (2.6.4)
89
+ mime-types (>= 1.16, < 4)
90
+ method_source (0.8.2)
91
+ mime-types (3.1)
92
+ mime-types-data (~> 3.2015)
93
+ mime-types-data (3.2016.0521)
94
+ mini_portile2 (2.1.0)
95
+ minitest (5.9.1)
96
+ multi_json (1.12.1)
97
+ nio4r (1.2.1)
98
+ nokogiri (1.6.8.1)
99
+ mini_portile2 (~> 2.1.0)
100
+ puma (3.6.2)
101
+ rack (2.0.1)
102
+ rack-test (0.6.3)
103
+ rack (>= 1.0)
104
+ rails (5.0.0.1)
105
+ actioncable (= 5.0.0.1)
106
+ actionmailer (= 5.0.0.1)
107
+ actionpack (= 5.0.0.1)
108
+ actionview (= 5.0.0.1)
109
+ activejob (= 5.0.0.1)
110
+ activemodel (= 5.0.0.1)
111
+ activerecord (= 5.0.0.1)
112
+ activesupport (= 5.0.0.1)
113
+ bundler (>= 1.3.0, < 2.0)
114
+ railties (= 5.0.0.1)
115
+ sprockets-rails (>= 2.0.0)
116
+ rails-dom-testing (2.0.1)
117
+ activesupport (>= 4.2.0, < 6.0)
118
+ nokogiri (~> 1.6.0)
119
+ rails-html-sanitizer (1.0.3)
120
+ loofah (~> 2.0)
121
+ railties (5.0.0.1)
122
+ actionpack (= 5.0.0.1)
123
+ activesupport (= 5.0.0.1)
124
+ method_source
125
+ rake (>= 0.8.7)
126
+ thor (>= 0.18.1, < 2.0)
127
+ rake (11.3.0)
128
+ rb-fsevent (0.9.8)
129
+ rb-inotify (0.9.7)
130
+ ffi (>= 0.5.0)
131
+ rspec-core (3.5.4)
132
+ rspec-support (~> 3.5.0)
133
+ rspec-expectations (3.5.0)
134
+ diff-lcs (>= 1.2.0, < 2.0)
135
+ rspec-support (~> 3.5.0)
136
+ rspec-mocks (3.5.0)
137
+ diff-lcs (>= 1.2.0, < 2.0)
138
+ rspec-support (~> 3.5.0)
139
+ rspec-rails (3.5.1)
140
+ actionpack (>= 3.0)
141
+ activesupport (>= 3.0)
142
+ railties (>= 3.0)
143
+ rspec-core (~> 3.5.0)
144
+ rspec-expectations (~> 3.5.0)
145
+ rspec-mocks (~> 3.5.0)
146
+ rspec-support (~> 3.5.0)
147
+ rspec-support (3.5.0)
148
+ sass (3.4.22)
149
+ sass-rails (5.0.6)
150
+ railties (>= 4.0.0, < 6)
151
+ sass (~> 3.1)
152
+ sprockets (>= 2.8, < 4.0)
153
+ sprockets-rails (>= 2.0, < 4.0)
154
+ tilt (>= 1.1, < 3)
155
+ spring (2.0.0)
156
+ activesupport (>= 4.2)
157
+ spring-watcher-listen (2.0.1)
158
+ listen (>= 2.7, < 4.0)
159
+ spring (>= 1.2, < 3.0)
160
+ sprockets (3.7.0)
161
+ concurrent-ruby (~> 1.0)
162
+ rack (> 1, < 3)
163
+ sprockets-rails (3.2.0)
164
+ actionpack (>= 4.0)
165
+ activesupport (>= 4.0)
166
+ sprockets (>= 3.0.0)
167
+ sqlite3 (1.3.12)
168
+ thor (0.19.4)
169
+ thread_safe (0.3.5)
170
+ tilt (2.0.5)
171
+ turbolinks (5.0.1)
172
+ turbolinks-source (~> 5)
173
+ turbolinks-source (5.0.0)
174
+ tzinfo (1.2.2)
175
+ thread_safe (~> 0.1)
176
+ uglifier (3.0.3)
177
+ execjs (>= 0.3.0, < 3)
178
+ virtus (1.0.5)
179
+ axiom-types (~> 0.1)
180
+ coercible (~> 1.0)
181
+ descendants_tracker (~> 0.0, >= 0.0.3)
182
+ equalizer (~> 0.0, >= 0.0.9)
183
+ web-console (3.4.0)
184
+ actionview (>= 5.0)
185
+ activemodel (>= 5.0)
186
+ debug_inspector
187
+ railties (>= 5.0)
188
+ websocket-driver (0.6.4)
189
+ websocket-extensions (>= 0.1.0)
190
+ websocket-extensions (0.1.2)
191
+
192
+ PLATFORMS
193
+ ruby
194
+
195
+ DEPENDENCIES
196
+ at_your_service!
197
+ byebug
198
+ coffee-rails (~> 4.2)
199
+ jbuilder (~> 2.5)
200
+ jquery-rails
201
+ listen (~> 3.0.5)
202
+ puma (~> 3.0)
203
+ rails (~> 5.0.0, >= 5.0.0.1)
204
+ rspec-rails
205
+ sass-rails (~> 5.0)
206
+ spring
207
+ spring-watcher-listen (~> 2.0.0)
208
+ sqlite3
209
+ turbolinks (~> 5)
210
+ tzinfo-data
211
+ uglifier (>= 1.3.0)
212
+ virtus
213
+ web-console
214
+
215
+ BUNDLED WITH
216
+ 1.12.5