reloj 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 42da7fc580502d942eb23f8aa85102338741a544
4
- data.tar.gz: 23060fa9e00ad5ced9d20dc86421283e398ab73d
3
+ metadata.gz: 0900113d767f58cdb927a7a5fd0df386020402a1
4
+ data.tar.gz: f3f871588d9070b720f1d32b7c00fa39ede22eb0
5
5
  SHA512:
6
- metadata.gz: 0d4eaaa5e8874830e9105d1bd68c492dfb4ee7aa65c0a0530ca1ca7c871cd569a38cf9f841252593b29202c77da8234dea73a20c756051ac3029d8d879fb30d2
7
- data.tar.gz: 9fce521ca07a2c63c5dd6bd25ab6b2c322093597551ba4b5b163ca678cc904dbdbe2a6d0b54c1d13efcdc21569234818161b242fa21e06024de2a73913f6140d
6
+ metadata.gz: aaea01ab0d4ae2201e0b64c17b8c93238c465262aa510f0421008620453085ae6c0a73b7eb860ed5fe949ebbb90c44d93cc5b822fe25c23f9462f4185da49c0a
7
+ data.tar.gz: a6e70a038678d2f48d4f0a819a137213fd7f3d55b54ca4f7e532a9433aef469f33b07c62930f38c9b07442810ac12adb863765ef726365734794debea7bd033e
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- reloj (0.1.4)
4
+ reloj (0.1.7)
5
5
  activesupport (~> 4.2)
6
6
  pg (~> 0.18)
7
7
  require_all (~> 1.3)
data/README.md CHANGED
@@ -141,4 +141,10 @@ Reloj is built to make deploying to heroku as easy as possible, here's how:
141
141
 
142
142
  heroku open
143
143
 
144
- Enjoy your now-deployed app!
144
+ Enjoy your now-deployed app!
145
+
146
+ ## TODO
147
+ * WEBrick doesn't support PATCH/DELETE (I think). Maybe I can monkey-patch that in using servlets
148
+ * Right now it doesn't serve assets. I think I can get it that work using servlets, also.
149
+ * REFERENCE: [http://ruby-doc.org/stdlib-1.9.3/libdoc/webrick/rdoc/WEBrick.html#module-WEBrick-label-Servlets](http://ruby-doc.org/stdlib-1.9.3/libdoc/webrick/rdoc/WEBrick.html#module-WEBrick-label-Servlets)
150
+
@@ -1,16 +1,18 @@
1
1
  require_relative 'pg_db'
2
2
  require 'active_support/inflector'
3
+ require 'byebug'
3
4
 
4
5
  class ModelBase
5
6
 
6
7
  # rough idea on how to replace self.finalize!
7
8
  # need to run at end of class definiton, not beginning
9
+ # could work if isntead of calling tablename i call self.to_s.tableize
8
10
  # def self.inherited(subclass)
9
11
  # attr_writer(*subclass.columns)
10
12
  # end
11
13
 
12
14
  def self.columns
13
- result = Database.execute(<<-SQL)
15
+ @columns ||= Database.execute(<<-SQL).fields.map(&:to_sym)
14
16
  SELECT
15
17
  *
16
18
  FROM
@@ -18,8 +20,6 @@ class ModelBase
18
20
  LIMIT
19
21
  0;
20
22
  SQL
21
-
22
- result.fields.map(&:to_sym)
23
23
  end
24
24
 
25
25
  def self.finalize!
@@ -62,16 +62,16 @@ class ModelBase
62
62
  end
63
63
 
64
64
  def self.find(id)
65
- x = Database.execute(<<-SQL, id)
65
+ res = Database.execute(<<-SQL, [id])
66
66
  SELECT
67
67
  *
68
68
  FROM
69
69
  #{table_name}
70
70
  WHERE
71
- id = ?;
71
+ id = $1;
72
72
  SQL
73
73
 
74
- x.empty? ? nil : self.new(x.first)
74
+ res.num_tuples.zero? ? nil : self.new(res.first)
75
75
  end
76
76
 
77
77
  def initialize(params = {})
@@ -93,35 +93,48 @@ class ModelBase
93
93
  end
94
94
  end
95
95
 
96
+ def not_id_attribute_values
97
+ self.class.columns.drop(1).map { |column| self.send(column) }
98
+ end
99
+
96
100
  def insert
97
- my_columns = self.class.columns
101
+ my_columns = self.class.columns.drop(1)
98
102
  col_names = my_columns.join(", ")
99
103
  n = my_columns.length
100
- question_marks = (["?"] * n).join(", ")
104
+ placeholders = [*1..n].map { |num| "$" + num.to_s }.join(', ')
101
105
 
102
- response = Database.execute(<<-SQL, self.attribute_values)
106
+ response = Database.execute(<<-SQL, self.not_id_attribute_values)
103
107
  INSERT INTO
104
108
  #{self.class.table_name} (#{col_names})
105
109
  VALUES
106
- (#{question_marks})
110
+ (#{placeholders})
107
111
  RETURNING
108
112
  id;
109
113
  SQL
110
114
  self.id = response[0]['id'].to_i
111
115
  end
112
116
 
117
+ def destroy
118
+ Database.execute(<<-SQL)
119
+ DELETE FROM
120
+ #{self.class.table_name}
121
+ WHERE
122
+ id = #{self.id};
123
+ SQL
124
+ end
125
+
113
126
  def update
114
- columns_line = self.class.columns.map do |col_name|
115
- "#{col_name} = ?"
127
+ columns_line = self.class.columns.map.with_index do |col_name, i|
128
+ "#{col_name} = $#{i + 1}"
116
129
  end.join(", ")
117
130
 
118
- Database.execute(<<-SQL, self.attribute_values, self.id)
131
+ Database.execute(<<-SQL, self.attribute_values)
119
132
  UPDATE
120
133
  #{self.class.table_name}
121
134
  SET
122
135
  #{columns_line}
123
136
  WHERE
124
- id = ?;
137
+ id = #{self.id};
125
138
  SQL
126
139
  end
127
140
 
@@ -52,7 +52,15 @@ class Database
52
52
  end
53
53
 
54
54
  def self.execute(*args)
55
+ pretty_print_sql(*args)
55
56
  instance.exec(*args)
56
57
  end
57
58
 
59
+ def self.pretty_print_sql(*sql_args)
60
+ pretty = sql_args.map do |a|
61
+ a.is_a?(String) ? a.gsub(/\s+/, " ").gsub(/;\s/, ";\n") : a.join(", ")
62
+ end.join("\n")
63
+ print "\n#{pretty}\n"
64
+ end
65
+
58
66
  end
@@ -13,7 +13,6 @@ class CatsController < Reloj::ControllerBase
13
13
  session['count'] ||= 0
14
14
  session['count'] += 1
15
15
  @cats = Cat.all
16
- p @cats
17
16
  render :index
18
17
  end
19
18
 
@@ -0,0 +1,10 @@
1
+ module App
2
+ ROUTES = Proc.new do
3
+ # put the routes for your app here, e.g.
4
+ # get '/cats/:cat_id/statuses', StatusesController, :index
5
+
6
+ get '/cats', CatsController, :index
7
+ get '/cats/new', CatsController, :new
8
+ post '/cats', CatsController, :create
9
+ end
10
+ end
@@ -0,0 +1,46 @@
1
+ DROP TABLE IF EXISTS cats;
2
+ CREATE TABLE cats (
3
+ id SERIAL PRIMARY KEY,
4
+ name VARCHAR(255) NOT NULL,
5
+ owner_id INTEGER
6
+
7
+ -- FOREIGN KEY(owner_id) REFERENCES humans(id)
8
+ );
9
+
10
+ DROP TABLE IF EXISTS humans;
11
+ CREATE TABLE humans (
12
+ id INTEGER PRIMARY KEY,
13
+ fname VARCHAR(255) NOT NULL,
14
+ lname VARCHAR(255) NOT NULL,
15
+ house_id INTEGER
16
+
17
+ -- FOREIGN KEY(house_id) REFERENCES houses(id)
18
+ );
19
+
20
+ DROP TABLE IF EXISTS houses;
21
+ CREATE TABLE houses (
22
+ id INTEGER PRIMARY KEY,
23
+ address VARCHAR(255) NOT NULL
24
+ );
25
+
26
+ INSERT INTO
27
+ houses (id, address)
28
+ VALUES
29
+ (1, '26th and Guerrero'), (2, 'Dolores and Market');
30
+
31
+ INSERT INTO
32
+ humans (id, fname, lname, house_id)
33
+ VALUES
34
+ (1, 'Devon', 'Watts', 1),
35
+ (2, 'Matt', 'Rubens', 1),
36
+ (3, 'Ned', 'Ruggeri', 2),
37
+ (4, 'Catless', 'Human', NULL);
38
+
39
+ INSERT INTO
40
+ cats (name, owner_id)
41
+ VALUES
42
+ ('Breakfast', 1),
43
+ ('Earl', 2),
44
+ ('Haskell', 3),
45
+ ('Markov', 3),
46
+ ('Stray Cat', NULL);
@@ -0,0 +1,27 @@
1
+ class TodosController < Reloj::ControllerBase
2
+
3
+ def index
4
+ @todos = Todo.all
5
+ render :index
6
+ end
7
+
8
+ def new
9
+ @todo = Todo.new
10
+ render :new
11
+ end
12
+
13
+ def create
14
+ @todo = Todo.new(params[:todo])
15
+ if @todo.title == "" || @todo.save
16
+ redirect_to "/"
17
+ else
18
+ render :new
19
+ end
20
+ end
21
+
22
+ def destroy
23
+ @todo = Todo.find(params[:id])
24
+ @todo.destroy
25
+ render_content("{}", "application/json")
26
+ end
27
+ end
File without changes
@@ -0,0 +1,4 @@
1
+ class Todo < ModelBase
2
+
3
+ finalize!
4
+ end
File without changes
@@ -0,0 +1,76 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
8
+ </head>
9
+ <body>
10
+
11
+ <nav class="navbar navbar-default">
12
+ <div class="container-fluid">
13
+ <!-- Brand and toggle get grouped for better mobile display -->
14
+ <div class="navbar-header">
15
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
16
+ <span class="sr-only">Toggle navigation</span>
17
+ <span class="icon-bar"></span>
18
+ <span class="icon-bar"></span>
19
+ <span class="icon-bar"></span>
20
+ </button>
21
+ <a class="navbar-brand" href="/">Todo app Build with Reloj</a>
22
+ </div>
23
+
24
+ <!-- Collect the nav links, forms, and other content for toggling -->
25
+ <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
26
+ <ul class="nav navbar-nav navbar-right">
27
+ <li><a href="http://github.com/ougarcia/reloj">GitHub</a></li>
28
+ </ul>
29
+ </div><!-- /.navbar-collapse -->
30
+ </div><!-- /.container-fluid -->
31
+ </nav>
32
+
33
+ <div class="container-fluid">
34
+ <div class="row">
35
+ <div class="col-xs-8 col-xs-offset-2 col-sm-6 col-sm-offset-3">
36
+ <h1>Todos</h1>
37
+
38
+ <div class="panel panel-default">
39
+ <ul class="list-group">
40
+ <% @todos.each do |todo| %>
41
+ <li class="list-group-item">
42
+ <%= todo.title %>
43
+ <button data-id="<%= todo.id %>" class="btn btn-danger btn-xs pull-right" type="submit">
44
+ Done
45
+ </button>
46
+ </li>
47
+ <% end %>
48
+ </ul>
49
+
50
+ <div class="panel-footer">
51
+ <a href="/todos/new" class="btn btn-primary btn-lg btn-block">
52
+ New Todo
53
+ </a>
54
+ </div>
55
+
56
+ </div>
57
+ </div>
58
+ </div>
59
+ </div>
60
+ <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
61
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
62
+ <!-- until I build an asset pipeline, I'll have to make do with CDNs & inline js -->
63
+ <script>
64
+ $('button.btn-danger').on('click', function(e) {
65
+ e.preventDefault();
66
+ var $currentTarget = $(e.currentTarget);
67
+ var id = $currentTarget.data('id');
68
+ $currentTarget.parent().remove();
69
+ $.ajax({
70
+ url: "/todos/" + id + '/delete',
71
+ method: "POST"
72
+ });
73
+ });
74
+ </script>
75
+ </body>
76
+ </html>
@@ -0,0 +1,66 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
8
+ </head>
9
+ <body>
10
+
11
+ <nav class="navbar navbar-default">
12
+ <div class="container-fluid">
13
+ <!-- Brand and toggle get grouped for better mobile display -->
14
+ <div class="navbar-header">
15
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
16
+ <span class="sr-only">Toggle navigation</span>
17
+ <span class="icon-bar"></span>
18
+ <span class="icon-bar"></span>
19
+ <span class="icon-bar"></span>
20
+ </button>
21
+ <a class="navbar-brand" href="/">Todo app Build with Reloj</a>
22
+ </div>
23
+
24
+ <!-- Collect the nav links, forms, and other content for toggling -->
25
+ <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
26
+ <ul class="nav navbar-nav navbar-right">
27
+ <li><a href="http://github.com/ougarcia/reloj">GitHub</a></li>
28
+ </ul>
29
+ </div><!-- /.navbar-collapse -->
30
+ </div><!-- /.container-fluid -->
31
+ </nav>
32
+
33
+ <div class="container-fluid">
34
+ <div class="row">
35
+ <div class="col-xs-8 col-xs-offset-2 col-sm-6 col-sm-offset-3">
36
+
37
+ <h1>New Todo</h1>
38
+ <form action="/todos" method="POST">
39
+ <div class="form-group">
40
+ <label for="todo-title">Title</label>
41
+ <input type="text" class="form-control" name="todo[title]">
42
+ </div>
43
+ <input
44
+ type="submit"
45
+ class="btn btn-primary btn-lg btn-block"
46
+ value="submit"
47
+ disabled="disabled"
48
+ >
49
+ </form>
50
+
51
+ </div>
52
+ </div>
53
+ </div>
54
+ </body>
55
+ <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
56
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
57
+ <script>
58
+ $('input:text').keyup(function () {
59
+ var disable = false;
60
+ if ( $('input:text').val() === "" ) {
61
+ disable = true
62
+ }
63
+ $('input:submit').prop('disabled', disable);
64
+ });
65
+ </script>
66
+ </html>
@@ -0,0 +1,2 @@
1
+ ---
2
+ :dbname: reloj_sample
@@ -1,10 +1,11 @@
1
1
  module App
2
2
  ROUTES = Proc.new do
3
- # put the routes for your app here, e.g.
4
- # get '/cats/:cat_id/statuses', StatusesController, :index
5
3
 
6
- get '/cats', CatsController, :index
7
- get '/cats/new', CatsController, :new
8
- post '/cats', CatsController, :create
4
+ get '/', TodosController, :index
5
+ get '/todos', TodosController, :index
6
+ get '/todos/new', TodosController, :new
7
+ post '/todos/:id/delete', TodosController, :destroy
8
+ post '/todos', TodosController, :create
9
+
9
10
  end
10
11
  end
File without changes
@@ -1,46 +1,15 @@
1
- DROP TABLE IF EXISTS cats;
2
- CREATE TABLE cats (
3
- id INTEGER PRIMARY KEY,
4
- name VARCHAR(255) NOT NULL,
5
- owner_id INTEGER
6
-
7
- -- FOREIGN KEY(owner_id) REFERENCES humans(id)
8
- );
9
-
10
- DROP TABLE IF EXISTS humans;
11
- CREATE TABLE humans (
12
- id INTEGER PRIMARY KEY,
13
- fname VARCHAR(255) NOT NULL,
14
- lname VARCHAR(255) NOT NULL,
15
- house_id INTEGER
16
-
17
- -- FOREIGN KEY(house_id) REFERENCES houses(id)
18
- );
19
-
20
- DROP TABLE IF EXISTS houses;
21
- CREATE TABLE houses (
22
- id INTEGER PRIMARY KEY,
23
- address VARCHAR(255) NOT NULL
1
+ DROP TABLE IF EXISTS todos;
2
+ CREATE TABLE todos (
3
+ id SERIAL PRIMARY KEY,
4
+ title VARCHAR(255) NOT NULL
24
5
  );
25
6
 
26
7
  INSERT INTO
27
- houses (id, address)
28
- VALUES
29
- (1, '26th and Guerrero'), (2, 'Dolores and Market');
30
-
31
- INSERT INTO
32
- humans (id, fname, lname, house_id)
33
- VALUES
34
- (1, 'Devon', 'Watts', 1),
35
- (2, 'Matt', 'Rubens', 1),
36
- (3, 'Ned', 'Ruggeri', 2),
37
- (4, 'Catless', 'Human', NULL);
38
-
39
- INSERT INTO
40
- cats (id, name, owner_id)
8
+ todos (title)
41
9
  VALUES
42
- (1, 'Breakfast', 1),
43
- (2, 'Earl', 2),
44
- (3, 'Haskell', 3),
45
- (4, 'Markov', 3),
46
- (5, 'Stray Cat', NULL);
10
+ ('Laundry'),
11
+ ('Buy Groceries'),
12
+ ('Water Plants'),
13
+ ('Run Dishwasher'),
14
+ ('Walk the Dog'),
15
+ ('Clean Room');
data/lib/reloj/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Reloj
2
- VERSION = "0.1.7"
2
+ VERSION = "0.1.8"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reloj
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - ougarcia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-10 00:00:00.000000000 Z
11
+ date: 2015-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -171,11 +171,22 @@ files:
171
171
  - lib/reloj/skeletons/new_app/app/views/.keep
172
172
  - lib/reloj/skeletons/new_app/config/routes.rb
173
173
  - lib/reloj/skeletons/new_app/db/.keep
174
- - lib/reloj/skeletons/sample_app/app/controllers/cats_controller.rb
175
- - lib/reloj/skeletons/sample_app/app/models/cat.rb
176
- - lib/reloj/skeletons/sample_app/app/views/cats_controller/index.html.erb
177
- - lib/reloj/skeletons/sample_app/app/views/cats_controller/new.html.erb
174
+ - lib/reloj/skeletons/old_example/app/controllers/cats_controller.rb
175
+ - lib/reloj/skeletons/old_example/app/models/cat.rb
176
+ - lib/reloj/skeletons/old_example/app/views/cats_controller/index.html.erb
177
+ - lib/reloj/skeletons/old_example/app/views/cats_controller/new.html.erb
178
+ - lib/reloj/skeletons/old_example/config/routes.rb
179
+ - lib/reloj/skeletons/old_example/db/setup.sql
180
+ - lib/reloj/skeletons/sample_app/app/controllers/.keep
181
+ - lib/reloj/skeletons/sample_app/app/controllers/todos_controller.rb
182
+ - lib/reloj/skeletons/sample_app/app/models/.keep
183
+ - lib/reloj/skeletons/sample_app/app/models/todo.rb
184
+ - lib/reloj/skeletons/sample_app/app/views/.keep
185
+ - lib/reloj/skeletons/sample_app/app/views/todos_controller/index.html.erb
186
+ - lib/reloj/skeletons/sample_app/app/views/todos_controller/new.html.erb
187
+ - lib/reloj/skeletons/sample_app/config/db.yml
178
188
  - lib/reloj/skeletons/sample_app/config/routes.rb
189
+ - lib/reloj/skeletons/sample_app/db/.keep
179
190
  - lib/reloj/skeletons/sample_app/db/setup.sql
180
191
  - lib/reloj/version.rb
181
192
  - reloj.gemspec