trails-mvc 0.1.0

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 (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.gitmodules +0 -0
  4. data/.rspec +2 -0
  5. data/Gemfile +5 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +74 -0
  8. data/Rakefile +2 -0
  9. data/bin/console +14 -0
  10. data/bin/server.rb +31 -0
  11. data/bin/setup +8 -0
  12. data/bin/trails +4 -0
  13. data/dynamic-archive/.rspec +2 -0
  14. data/dynamic-archive/.ruby-version +1 -0
  15. data/dynamic-archive/Gemfile +6 -0
  16. data/dynamic-archive/Gemfile.lock +38 -0
  17. data/dynamic-archive/README.md +40 -0
  18. data/dynamic-archive/lib/associatable.rb +145 -0
  19. data/dynamic-archive/lib/base.rb +143 -0
  20. data/dynamic-archive/lib/db_connection.rb +151 -0
  21. data/dynamic-archive/lib/searchable.rb +39 -0
  22. data/dynamic-archive/lib/validatable.rb +71 -0
  23. data/dynamic-archive/spec/associatable_spec.rb +294 -0
  24. data/dynamic-archive/spec/base_spec.rb +252 -0
  25. data/dynamic-archive/spec/searchable_spec.rb +44 -0
  26. data/dynamic-archive/spec/validatable_spec.rb +81 -0
  27. data/dynamic-archive/testing_database/database.db +0 -0
  28. data/dynamic-archive/testing_database/database.rb +6 -0
  29. data/dynamic-archive/testing_database/migrations/bats_migration.sql +7 -0
  30. data/dynamic-archive/testing_database/migrations/cats_migration.sql +7 -0
  31. data/dynamic-archive/testing_database/migrations/houses_migration.sql +4 -0
  32. data/dynamic-archive/testing_database/migrations/humans_migration.sql +8 -0
  33. data/dynamic-archive/testing_database/migrations/play_times_migration.sql +8 -0
  34. data/dynamic-archive/testing_database/migrations/toys_migration.sql +4 -0
  35. data/dynamic-archive/testing_database/schema.sql +44 -0
  36. data/dynamic-archive/testing_database/seed.sql +44 -0
  37. data/lib/asset_server.rb +28 -0
  38. data/lib/cli.rb +109 -0
  39. data/lib/controller_base.rb +78 -0
  40. data/lib/exception_handler.rb +14 -0
  41. data/lib/flash.rb +24 -0
  42. data/lib/router.rb +61 -0
  43. data/lib/session.rb +28 -0
  44. data/lib/trails.rb +30 -0
  45. data/lib/version.rb +3 -0
  46. data/public/assets/application.css +231 -0
  47. data/public/assets/application.js +9 -0
  48. data/template/Gemfile +1 -0
  49. data/template/README.md +0 -0
  50. data/template/app/controllers/application_controller.rb +2 -0
  51. data/template/app/controllers/static_controller.rb +4 -0
  52. data/template/app/views/layouts/application.html.erb +15 -0
  53. data/template/app/views/static/root.html.erb +73 -0
  54. data/template/config/database.rb +6 -0
  55. data/template/config/routes.rb +17 -0
  56. data/template/db/database.db +0 -0
  57. data/template/db/database.sql +0 -0
  58. data/template/db/schema.sql +0 -0
  59. data/template/db/seed.sql +0 -0
  60. data/template/public/assets/application.css +1 -0
  61. data/template/public/assets/application.js +1 -0
  62. data/trails-mvc.gemspec +42 -0
  63. metadata +257 -0
@@ -0,0 +1,78 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext'
3
+ require 'active_support/inflector'
4
+ require 'erb'
5
+ require_relative './session'
6
+ require_relative './flash'
7
+
8
+ module TrailsController
9
+ class Base
10
+ attr_reader :req, :res, :params
11
+
12
+ def initialize(req, res, route_params = {})
13
+ @req = req
14
+ @res = res
15
+ @params = req.params.merge(route_params)
16
+ @already_built_response = false
17
+ end
18
+
19
+ def already_built_response?
20
+ @already_built_response
21
+ end
22
+
23
+ def flash
24
+ @flash ||= Flash.new(@req)
25
+ end
26
+
27
+ def redirect_to(url)
28
+ raise 'Response already built' if already_built_response?
29
+
30
+ res.status = 302
31
+ res['Location'] = url
32
+ session.store_session(res)
33
+ flash.store_flash(res)
34
+
35
+ @already_built_response = true
36
+ end
37
+
38
+ def render_content(content, content_type)
39
+ raise 'Cannot render twice' if already_built_response?
40
+
41
+ res['Content-Type'] = content_type
42
+ res.write(content)
43
+ session.store_session(res)
44
+ flash.store_flash(res)
45
+
46
+ @already_built_response = true
47
+ end
48
+
49
+ def render_partial(params = {})
50
+ defaults = {
51
+ view_dir: self.class.name.underscore[0..-12],
52
+ template: @__template_name
53
+ }
54
+ params = defaults.merge(params)
55
+
56
+ file_path = "app/views/#{params[:view_dir]}/#{params[:template]}.html.erb"
57
+ file_contents = File.read(file_path)
58
+ ERB.new(file_contents).result(binding)
59
+ end
60
+
61
+ def render(template_name)
62
+ app_template = File.read("app/views/layouts/application.html.erb")
63
+ @__template_name = template_name
64
+
65
+ result = ERB.new(app_template).result(binding)
66
+ render_content(result, 'text/html')
67
+ end
68
+
69
+ def session
70
+ @session ||= Session.new(@req)
71
+ end
72
+
73
+ def invoke_action(name)
74
+ send(name)
75
+ render(name) unless already_built_response?
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,14 @@
1
+ class ExceptionHandler
2
+ def initialize(app)
3
+ @app = app
4
+ @res = Rack::Response.new
5
+ end
6
+
7
+ def call(env)
8
+ begin
9
+ app.call(env)
10
+ rescue => e
11
+ puts e
12
+ end
13
+ end
14
+ end
data/lib/flash.rb ADDED
@@ -0,0 +1,24 @@
1
+ class Flash
2
+ attr_reader :now, :later
3
+
4
+ def initialize(req)
5
+ messages = req.cookies["_trails_flash"]
6
+ @now = JSON.parse(messages) if messages
7
+ @now ||= {}
8
+ @later = {}
9
+ end
10
+
11
+ def [](message_type)
12
+ now[message_type]
13
+ end
14
+
15
+ def []=(message_type, value)
16
+ later[message_type] = value
17
+ end
18
+
19
+ def store_flash(res)
20
+ self[:path] = "/"
21
+ self[:value] = later.to_json
22
+ res.set_cookie("_trails_flash", later)
23
+ end
24
+ end
data/lib/router.rb ADDED
@@ -0,0 +1,61 @@
1
+ class Route
2
+ attr_reader :pattern, :http_method, :controller_class, :action_name
3
+
4
+ def initialize(pattern, http_method, controller_class, action_name)
5
+ @pattern = pattern
6
+ @http_method = http_method
7
+ @controller_class = controller_class
8
+ @action_name = action_name
9
+ end
10
+
11
+ def matches?(req)
12
+ pattern =~ req.path && req.request_method.downcase.to_sym == http_method
13
+ end
14
+
15
+ def run(req, res)
16
+ match_data = pattern.match(req.path)
17
+
18
+ route_params = { }
19
+ match_data.names.each { |name| route_params[name] = match_data[name] }
20
+
21
+ controller = controller_class.new(req, res, route_params)
22
+ controller.invoke_action(action_name)
23
+ end
24
+ end
25
+
26
+ class Router
27
+ attr_reader :routes
28
+
29
+ def initialize
30
+ @routes = []
31
+ end
32
+
33
+ def add_route(pattern, method, controller_class, action_name)
34
+ routes << Route.new(pattern, method, controller_class, action_name)
35
+ end
36
+
37
+ def draw(&proc)
38
+ instance_eval(&proc)
39
+ end
40
+
41
+ [:get, :post, :put, :delete].each do |http_method|
42
+ define_method(http_method) do |pattern, controller_class, action_name|
43
+ add_route(pattern, http_method, controller_class, action_name)
44
+ end
45
+ end
46
+
47
+ def match(req)
48
+ routes.find { |route| route.matches?(req) }
49
+ end
50
+
51
+ def run(req, res)
52
+ route = match(req)
53
+
54
+ if route
55
+ route.run(req, res)
56
+ else
57
+ res.status = 404
58
+ res.write("Not Found")
59
+ end
60
+ end
61
+ end
data/lib/session.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'json'
2
+
3
+ class Session
4
+ def initialize(req)
5
+ cookie = req.cookies["_trails_app"]
6
+ if cookie
7
+ @data = JSON.parse(cookie)
8
+ else
9
+ @data = {}
10
+ end
11
+ end
12
+
13
+ def [](key)
14
+ @data[key]
15
+ end
16
+
17
+ def []=(key, val)
18
+ @data[key] = val
19
+ end
20
+
21
+ def store_session(res)
22
+ cookie = {
23
+ path: "/",
24
+ value: @data.to_json
25
+ }
26
+ res.set_cookie("_trails_app", cookie)
27
+ end
28
+ end
data/lib/trails.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'fileutils'
2
+ require 'pathname'
3
+ require_relative "version"
4
+
5
+ module Trails
6
+ def self.project_root
7
+ current_dir = Pathname.new(Dir.pwd)
8
+ current_dir.ascend do |dir|
9
+ gemfile = File.exist?(File.join(dir, 'Gemfile'))
10
+ app_dir = Dir.exist?(File.join(dir, 'app'))
11
+ return dir if gemfile && app_dir
12
+ end
13
+
14
+ nil
15
+ end
16
+ end
17
+
18
+ TRAILS_ROOT = /^(.+)\/lib/.match(File.dirname(__FILE__))[1]
19
+ TEMPLATE_PATH = File.join(TRAILS_ROOT, 'template')
20
+ PROJECT_ROOT = Trails.project_root
21
+
22
+ require_relative "#{PROJECT_ROOT}/config/database" if PROJECT_ROOT
23
+ require_relative 'controller_base'
24
+ require_relative 'router'
25
+ require_relative 'asset_server'
26
+ require_relative 'exception_handler'
27
+ require_relative "../dynamic-archive/lib/base"
28
+
29
+
30
+ require_relative "cli"
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module Trails
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,231 @@
1
+ /* RESET */
2
+ html, body, header, nav, h1, a,
3
+ ul, li, strong, main, button, i,
4
+ section, figure, img, div, h2, p, form,
5
+ fieldset, label, input, textarea,
6
+ span, article, footer, time, small {
7
+ margin: 0;
8
+ padding: 0;
9
+ border: 0;
10
+ outline: 0;
11
+ font: inherit;
12
+ color: inherit;
13
+ text-align: inherit;
14
+ text-decoration: inherit;
15
+ vertical-align: inherit;
16
+ box-sizing: inherit;
17
+ background: transparent;
18
+ list-style: none;
19
+ }
20
+
21
+ /* CLEARFIX */
22
+ .group:after {
23
+ content: "";
24
+ display: block;
25
+ clear: both;
26
+ }
27
+
28
+ body {
29
+ background-color: #F4F2F3;
30
+ font-family: 'Lato', Helvetica, sans-serif;
31
+ line-height: 1.3;
32
+ }
33
+
34
+ section.header {
35
+ position: fixed;
36
+ font-weight: 700;
37
+ z-index: 100;
38
+ top: 0;
39
+ padding: 40px 0;
40
+ width: 100%;
41
+ font-size: 21px;
42
+ -webkit-transition: padding 0.5s linear, background-color 0.5s linear;
43
+ -moz-transition: padding 0.5s linear, background-color 0.5s linear;
44
+ -o-transition: padding 0.5s linear, background-color 0.5s linear;
45
+ transition: padding 0.5s linear, background-color 0.5s linear;
46
+ }
47
+
48
+ section.header.sticky {
49
+ padding: 20px 0;
50
+ background-color: rgba(255, 255, 255, 0.6);
51
+ }
52
+
53
+ div.links {
54
+ width: 75%;
55
+ margin: auto;
56
+ }
57
+
58
+ section.header h1 {
59
+ float: left;
60
+ padding: 5px 10px;
61
+ }
62
+
63
+ section.header .nav {
64
+ float: right;
65
+ }
66
+
67
+ .nav > li {
68
+ float: left;
69
+ padding: 5px 10px;
70
+ }
71
+
72
+ a {
73
+ color: #928396;
74
+ -webkit-transition: color 0.2s linear;
75
+ -moz-transition: color 0.2s linear;
76
+ -o-transition: color 0.2s linear;
77
+ transition: color 0.2s linear;
78
+ }
79
+
80
+ a:hover {
81
+ color: #230903;
82
+ }
83
+
84
+ span.logout-text {
85
+ cursor: pointer;
86
+ color: #828489;
87
+ -webkit-transition: color 0.2s linear;
88
+ -moz-transition: color 0.2s linear;
89
+ -o-transition: color 0.2s linear;
90
+ transition: color 0.2s linear;
91
+ }
92
+
93
+ span.logout-text:hover {
94
+ color: #230903;
95
+ }
96
+
97
+ main {
98
+ box-sizing: border-box;
99
+ min-height: 90vh;
100
+ width: 75%;
101
+ margin: 50px auto 0 auto;
102
+ padding: 30px 10px 10px 10px;
103
+ }
104
+
105
+ section.footer {
106
+ box-sizing: border-box;
107
+ font-weight: 700;
108
+ color: #000000;
109
+ width: 75%;
110
+ margin: auto;
111
+ padding: 5px;
112
+ font-size: 18px;
113
+ }
114
+
115
+ section.footer a {
116
+ color: #656256;
117
+ -webkit-transition: color 0.2s linear;
118
+ -moz-transition: color 0.2s linear;
119
+ -o-transition: color 0.2s linear;
120
+ transition: color 0.2s linear;
121
+ }
122
+
123
+ section.footer a:hover {
124
+ color: #4D7EA8;
125
+ }
126
+
127
+ section.trails-splash {
128
+ min-height: 65vh;
129
+ position: relative;
130
+ }
131
+
132
+ section.splash-content {
133
+ position: absolute;
134
+ width: 100%;
135
+ top: 50%;
136
+ transform: translateY(-50%);
137
+ }
138
+
139
+ div.splash-img-container {
140
+ position: relative;
141
+ width: 40%;
142
+ margin: 40px auto;
143
+ }
144
+
145
+ img.splash-img {
146
+ display: block;
147
+ width: 100%;
148
+ }
149
+
150
+ p.photo-credit {
151
+ color: #F4F2F3;
152
+ font-size: 13px;
153
+ position: absolute;
154
+ right: 5px;
155
+ bottom: 5px;
156
+ }
157
+
158
+ h2.splash-header {
159
+ font-size: 72px;
160
+ }
161
+
162
+ h2 {
163
+ font-size: 40px;
164
+ font-weight: 700;
165
+ text-align: center;
166
+ }
167
+
168
+ h3 {
169
+ font-size: 30px;
170
+ }
171
+
172
+ h4 {
173
+ font-size: 26px;
174
+ }
175
+
176
+ p {
177
+ font-size: 20px;
178
+ }
179
+
180
+ li {
181
+ padding: 5px;
182
+ font-size: 22px;
183
+ }
184
+
185
+ ul.form-error-messages {
186
+ font-size: 14px;
187
+ color: #e63444;
188
+ }
189
+
190
+ p.success-messages {
191
+ font-size: 18px;
192
+ color: #e63444;
193
+ }
194
+
195
+ form.post-form {
196
+ max-width: 500px;
197
+ margin: 30px auto;
198
+ }
199
+
200
+ form.post-form label {
201
+ font-size: 22px;
202
+ }
203
+
204
+ form.post-form input {
205
+ box-sizing: border-box;
206
+ display: block;
207
+ margin: 7px 0;
208
+ padding: 7px;
209
+ height: 40px;
210
+ width: 100%;
211
+ border-radius: 3px;
212
+ background-color: rgba(255, 255, 255, 0.5);
213
+ }
214
+
215
+ button.new-entry {
216
+ margin-top: 10px;
217
+ font-size: 22px;
218
+ font-weight: 700;
219
+ padding: 8px 13px;
220
+ border-radius: 3px;
221
+ background-color: #9E90A2;
222
+ }
223
+
224
+ button.new-entry:hover {
225
+ cursor: pointer;
226
+ background-color: #83688b;
227
+ -webkit-transition: all 0.2s linear;
228
+ -moz-transition: all 0.2s linear;
229
+ -o-transition: all 0.2s linear;
230
+ transition: all 0.2s linear;
231
+ }
@@ -0,0 +1,9 @@
1
+ function handleScroll() {
2
+ if ($(window).scrollTop() > 20) {
3
+ $('section.header').addClass('sticky');
4
+ } else {
5
+ $('section.header').removeClass('sticky');
6
+ }
7
+ }
8
+
9
+ $(document).scroll(handleScroll);
data/template/Gemfile ADDED
@@ -0,0 +1 @@
1
+ source 'https://rubygems.org'
File without changes
@@ -0,0 +1,2 @@
1
+ class ApplicationController < TrailsController::Base
2
+ end
@@ -0,0 +1,4 @@
1
+ class StaticController < ApplicationController
2
+ def root
3
+ end
4
+ end
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Your Ruby on Trails App</title>
6
+ <link rel="stylesheet" href="/public/assets/application.css"charset="utf-8">
7
+ </head>
8
+ <body>
9
+ <main>
10
+ <!-- yields to the view -->
11
+ <%= render_partial %>
12
+ </main>
13
+ <script src="/public/assets/application.js"></script>
14
+ </body>
15
+ </html>
@@ -0,0 +1,73 @@
1
+ <section class="trails-splash">
2
+ <section class="splash-content">
3
+ <div class="splash-img-container">
4
+ <img
5
+ class="splash-img"
6
+ src="https://c1.staticflickr.com/1/677/22420965587_9602618f46_c.jpg" alt="" />
7
+ <p class="photo-credit">
8
+ photo by <a target="_blank" href="https://www.flickr.com/photos/annahesser/">annahesser</a> from Flickr
9
+ </p>
10
+ </div>
11
+ <h2 class="splash-header">Ruby on Trails</h2>
12
+ </section>
13
+ </section>
14
+ <h3>You're now hiking Ruby on Trails!</h3>
15
+ <h3><a target="_blank" href="https://github.com/wmcmeans/trails">View the Repository on GitHub</a></h3>
16
+ <p>
17
+ You can find all the code and details about how Ruby on Trails works, from
18
+ router to views, on the repository. I encourage you to take a look around it
19
+ to get a feel for just how powerful Trails can be.
20
+ </p>
21
+ <h2>Trails Guide</h2>
22
+ <h3><a target="_blank" href="https://github.com/wmcmeans/trails-sample">Trails Sample App Repository</a></h3>
23
+ <p>
24
+ Check out the Trails Sample App repository to get the best idea of how to use Trails
25
+ </p>
26
+
27
+ <h3>How to Get Started With Trails</h3>
28
+ <h4>Create Your First App</h4>
29
+ <p>
30
+ <code>trails new [name]</code><br>
31
+ begins a new Trails project
32
+ </p>
33
+
34
+ <h4>Start the Server</h4>
35
+ <p>
36
+ <code>trails server [--host] [--port]</code><br>
37
+ starts the Trails server; default host: localhost,
38
+ default port: 3000
39
+ </p>
40
+
41
+ <h4>Generate Models and Controllers</h4>
42
+ <p>
43
+ <code>trails generate model [model_name]</code><br>
44
+ creates a new model file in 'app/models' and a new migration in 'db/migrations'
45
+ <code>trails generate controller [controller_name]</code><br>
46
+ creates a new controller file in
47
+ 'app/controllers' and a corresponding view folder in 'app/views'
48
+ <code>trails generate migration [migration_name]</code><br>
49
+ creates a blank migration file in
50
+ 'db/migrations' (but no model file)
51
+ </p>
52
+
53
+ <h4>Change the Database</h4>
54
+ <p>
55
+ <code>trails db migrate</code><br>
56
+ runs all pending database migrations
57
+ <code>trails db seed</code><br>
58
+ seeds the database
59
+ <code>trails db reset</code><br>
60
+ clears the database, runs all migrations, and re-seeds
61
+ </p>
62
+
63
+ <h4>Add Routes</h4>
64
+ <p>
65
+ Follow the example in 'config/routes.rb'
66
+ </p>
67
+
68
+ <h4>Add CSS and JavaScript</h4>
69
+ <p>
70
+ It's recommended to add styling to 'public/assets/application.css' and any JavaScript
71
+ to 'public/assets/application.js'. You may also include other scripts and stylesheets
72
+ in your views as long as you store them in 'public/assets'.
73
+ </p>
@@ -0,0 +1,6 @@
1
+ ENV['ROOT_FOLDER'] = File.join(File.dirname(__FILE__), '../db')
2
+ ENV['MIGRATIONS_FOLDER'] = File.join(ENV['ROOT_FOLDER'], 'migrations')
3
+
4
+ ENV['SCHEMA_FILE'] = File.join(ENV['ROOT_FOLDER'], 'schema.sql')
5
+ ENV['SEED_FILE'] = File.join(ENV['ROOT_FOLDER'], 'seed.sql')
6
+ ENV['DB_FILE'] = File.join(ENV['ROOT_FOLDER'], 'database.db')
@@ -0,0 +1,17 @@
1
+ Dir.glob("#{PROJECT_ROOT}/app/models/*.rb") do |model_file|
2
+ require_relative model_file
3
+ end
4
+
5
+ require_relative "#{PROJECT_ROOT}/app/controllers/application_controller"
6
+ Dir.glob("#{PROJECT_ROOT}/app/controllers/*.rb") do |controller_file|
7
+ next if controller_file == 'application_controller'
8
+ require_relative controller_file
9
+ end
10
+
11
+
12
+ # Draw your routes here, format:
13
+ # get Regexp.new("^/trails/(?<id>\\d+)$"), HikingTrailsController, :show
14
+
15
+ ROUTES = Proc.new do
16
+ get Regexp.new("^/?$"), StaticController, :root
17
+ end
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1 @@
1
+ /* Your styles here! */
@@ -0,0 +1 @@
1
+ // It's recommended to put all JS here or require it here
@@ -0,0 +1,42 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "trails-mvc"
8
+ spec.version = Trails::VERSION
9
+ spec.authors = ["William McMeans"]
10
+ spec.email = ["wrmcmeans@gmail.com"]
11
+
12
+ spec.summary = %q{Ruby on Trails is a lightweight MVC framework}
13
+ spec.description = %q{Build rich web apps with a hiking them using Ruby on Trails}
14
+ spec.homepage = "http://www.ruby-on-trails.com/"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # delete this section to allow pushing this gem to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = "bin"
27
+ # spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.executables = ["trails"]
29
+ spec.require_paths = ["lib"]
30
+
31
+ spec.add_dependency "thor", "~> 0.19"
32
+ spec.add_dependency "httparty", "~> 0.13"
33
+ spec.add_dependency "rake", "~> 10.0"
34
+ spec.add_dependency "sqlite3", "~> 1.3", ">= 1.3.5"
35
+ spec.add_dependency "rack", "~> 1.6", ">= 1.6.4"
36
+ spec.add_dependency "activesupport", "~> 4.2", ">= 4.2.5.2"
37
+
38
+
39
+ spec.add_development_dependency "bundler", "~> 1.11"
40
+ spec.add_development_dependency "pry", "~> 0.10", ">= 0.10.3"
41
+ spec.add_development_dependency "rspec", "~> 3.1"
42
+ end