at_your_service 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +149 -0
- data/Rakefile +2 -0
- data/at_your_service.gemspec +26 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/at_your_service.rb +9 -0
- data/lib/at_your_service/error.rb +23 -0
- data/lib/at_your_service/service.rb +20 -0
- data/lib/at_your_service/success.rb +17 -0
- data/lib/at_your_service/version.rb +3 -0
- data/rails_test/rails_app/.gitignore +21 -0
- data/rails_test/rails_app/.rspec +2 -0
- data/rails_test/rails_app/Gemfile +28 -0
- data/rails_test/rails_app/Gemfile.lock +216 -0
- data/rails_test/rails_app/README.md +24 -0
- data/rails_test/rails_app/Rakefile +6 -0
- data/rails_test/rails_app/app/assets/config/manifest.js +3 -0
- data/rails_test/rails_app/app/assets/images/.keep +0 -0
- data/rails_test/rails_app/app/assets/javascripts/application.js +16 -0
- data/rails_test/rails_app/app/assets/javascripts/cable.js +13 -0
- data/rails_test/rails_app/app/assets/javascripts/channels/.keep +0 -0
- data/rails_test/rails_app/app/assets/stylesheets/application.css +15 -0
- data/rails_test/rails_app/app/channels/application_cable/channel.rb +4 -0
- data/rails_test/rails_app/app/channels/application_cable/connection.rb +4 -0
- data/rails_test/rails_app/app/controllers/application_controller.rb +9 -0
- data/rails_test/rails_app/app/controllers/concerns/.keep +0 -0
- data/rails_test/rails_app/app/helpers/application_helper.rb +2 -0
- data/rails_test/rails_app/app/jobs/application_job.rb +2 -0
- data/rails_test/rails_app/app/mailers/application_mailer.rb +4 -0
- data/rails_test/rails_app/app/models/application_record.rb +3 -0
- data/rails_test/rails_app/app/models/concerns/.keep +0 -0
- data/rails_test/rails_app/app/services/test_non_strict_service.rb +16 -0
- data/rails_test/rails_app/app/services/test_strict_service.rb +16 -0
- data/rails_test/rails_app/app/views/layouts/application.html.erb +14 -0
- data/rails_test/rails_app/app/views/layouts/mailer.html.erb +13 -0
- data/rails_test/rails_app/app/views/layouts/mailer.text.erb +1 -0
- data/rails_test/rails_app/bin/bundle +3 -0
- data/rails_test/rails_app/bin/rails +9 -0
- data/rails_test/rails_app/bin/rake +9 -0
- data/rails_test/rails_app/bin/setup +34 -0
- data/rails_test/rails_app/bin/spring +16 -0
- data/rails_test/rails_app/bin/update +29 -0
- data/rails_test/rails_app/config.ru +5 -0
- data/rails_test/rails_app/config/application.rb +16 -0
- data/rails_test/rails_app/config/boot.rb +3 -0
- data/rails_test/rails_app/config/cable.yml +9 -0
- data/rails_test/rails_app/config/database.yml +25 -0
- data/rails_test/rails_app/config/environment.rb +5 -0
- data/rails_test/rails_app/config/environments/development.rb +54 -0
- data/rails_test/rails_app/config/environments/production.rb +86 -0
- data/rails_test/rails_app/config/environments/test.rb +42 -0
- data/rails_test/rails_app/config/initializers/application_controller_renderer.rb +6 -0
- data/rails_test/rails_app/config/initializers/assets.rb +11 -0
- data/rails_test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/rails_test/rails_app/config/initializers/cookies_serializer.rb +5 -0
- data/rails_test/rails_app/config/initializers/filter_parameter_logging.rb +4 -0
- data/rails_test/rails_app/config/initializers/inflections.rb +16 -0
- data/rails_test/rails_app/config/initializers/mime_types.rb +4 -0
- data/rails_test/rails_app/config/initializers/new_framework_defaults.rb +24 -0
- data/rails_test/rails_app/config/initializers/session_store.rb +3 -0
- data/rails_test/rails_app/config/initializers/wrap_parameters.rb +14 -0
- data/rails_test/rails_app/config/locales/en.yml +23 -0
- data/rails_test/rails_app/config/puma.rb +47 -0
- data/rails_test/rails_app/config/routes.rb +5 -0
- data/rails_test/rails_app/config/secrets.yml +22 -0
- data/rails_test/rails_app/config/spring.rb +6 -0
- data/rails_test/rails_app/db/seeds.rb +7 -0
- data/rails_test/rails_app/lib/assets/.keep +0 -0
- data/rails_test/rails_app/lib/tasks/.keep +0 -0
- data/rails_test/rails_app/log/.keep +0 -0
- data/rails_test/rails_app/public/404.html +67 -0
- data/rails_test/rails_app/public/422.html +67 -0
- data/rails_test/rails_app/public/500.html +66 -0
- data/rails_test/rails_app/public/apple-touch-icon-precomposed.png +0 -0
- data/rails_test/rails_app/public/apple-touch-icon.png +0 -0
- data/rails_test/rails_app/public/favicon.ico +0 -0
- data/rails_test/rails_app/public/robots.txt +5 -0
- data/rails_test/rails_app/spec/rails_helper.rb +57 -0
- data/rails_test/rails_app/spec/services/test_non_strict_service_spec.rb +18 -0
- data/rails_test/rails_app/spec/services/test_strict_services_spec.rb +18 -0
- data/rails_test/rails_app/spec/spec_helper.rb +99 -0
- data/rails_test/rails_app/tmp/.keep +0 -0
- data/rails_test/rails_app/vendor/assets/javascripts/.keep +0 -0
- data/rails_test/rails_app/vendor/assets/stylesheets/.keep +0 -0
- metadata +190 -0
checksums.yaml
ADDED
@@ -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
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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
|
+
|
data/Rakefile
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 '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
|
data/bin/console
ADDED
@@ -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
|
data/bin/setup
ADDED
@@ -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,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,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
|