rails_lite 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 (80) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.gitignore +8 -0
  4. data/Gemfile +6 -0
  5. data/Gemfile.lock +22 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +39 -0
  8. data/Rakefile +2 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/exe/railslite +4 -0
  12. data/lib/.DS_Store +0 -0
  13. data/lib/rails_lite.rb +6 -0
  14. data/lib/rails_lite/.DS_Store +0 -0
  15. data/lib/rails_lite/cli.rb +65 -0
  16. data/lib/rails_lite/version.rb +3 -0
  17. data/lib/scaffold/.DS_Store +0 -0
  18. data/lib/scaffold/Gemfile +12 -0
  19. data/lib/scaffold/app/controllers/albums_controller.rb +55 -0
  20. data/lib/scaffold/app/controllers/application_controller.rb +45 -0
  21. data/lib/scaffold/app/controllers/bands_controller.rb +62 -0
  22. data/lib/scaffold/app/controllers/notes_controller.rb +26 -0
  23. data/lib/scaffold/app/controllers/sessions_controller.rb +34 -0
  24. data/lib/scaffold/app/controllers/tracks_controller.rb +55 -0
  25. data/lib/scaffold/app/controllers/users_controller.rb +41 -0
  26. data/lib/scaffold/app/models/album.rb +14 -0
  27. data/lib/scaffold/app/models/application_model.rb +5 -0
  28. data/lib/scaffold/app/models/band.rb +7 -0
  29. data/lib/scaffold/app/models/note.rb +7 -0
  30. data/lib/scaffold/app/models/track.rb +20 -0
  31. data/lib/scaffold/app/models/user.rb +42 -0
  32. data/lib/scaffold/app/views/albums_controller/edit.html.erb +51 -0
  33. data/lib/scaffold/app/views/albums_controller/new.html.erb +50 -0
  34. data/lib/scaffold/app/views/albums_controller/show.html.erb +25 -0
  35. data/lib/scaffold/app/views/application.html.erb +41 -0
  36. data/lib/scaffold/app/views/bands_controller/edit.html.erb +16 -0
  37. data/lib/scaffold/app/views/bands_controller/index.html.erb +12 -0
  38. data/lib/scaffold/app/views/bands_controller/json.json.jbuilder +3 -0
  39. data/lib/scaffold/app/views/bands_controller/new.html.erb +15 -0
  40. data/lib/scaffold/app/views/bands_controller/show.html.erb +27 -0
  41. data/lib/scaffold/app/views/sessions_controller/new.html.erb +22 -0
  42. data/lib/scaffold/app/views/tracks_controller/edit.html.erb +60 -0
  43. data/lib/scaffold/app/views/tracks_controller/new.html.erb +59 -0
  44. data/lib/scaffold/app/views/tracks_controller/show.html.erb +56 -0
  45. data/lib/scaffold/app/views/users_controller/new.html.erb +22 -0
  46. data/lib/scaffold/app/views/users_controller/show.html.erb +4 -0
  47. data/lib/scaffold/bin/pry +13 -0
  48. data/lib/scaffold/bin/routes +10 -0
  49. data/lib/scaffold/bin/server +32 -0
  50. data/lib/scaffold/config/routes.rb +26 -0
  51. data/lib/scaffold/db/database.db +0 -0
  52. data/lib/scaffold/db/database.sql +48 -0
  53. data/lib/scaffold/lib/.DS_Store +0 -0
  54. data/lib/scaffold/lib/controller/controller_base.rb +183 -0
  55. data/lib/scaffold/lib/controller/controller_callbacks.rb +17 -0
  56. data/lib/scaffold/lib/controller/cookies/flash.rb +33 -0
  57. data/lib/scaffold/lib/controller/cookies/flash_now.rb +15 -0
  58. data/lib/scaffold/lib/controller/cookies/session.rb +29 -0
  59. data/lib/scaffold/lib/controller/strong_params.rb +40 -0
  60. data/lib/scaffold/lib/middleware/file_server.rb +42 -0
  61. data/lib/scaffold/lib/middleware/show_exceptions.rb +62 -0
  62. data/lib/scaffold/lib/middleware/static.rb +31 -0
  63. data/lib/scaffold/lib/middleware/templates/rescue.html.erb +49 -0
  64. data/lib/scaffold/lib/model/associations/assoc_options.rb +16 -0
  65. data/lib/scaffold/lib/model/associations/associatable.rb +120 -0
  66. data/lib/scaffold/lib/model/associations/belongs_to_options.rb +18 -0
  67. data/lib/scaffold/lib/model/associations/has_many_options.rb +17 -0
  68. data/lib/scaffold/lib/model/db_connection.rb +59 -0
  69. data/lib/scaffold/lib/model/model_base.rb +183 -0
  70. data/lib/scaffold/lib/model/model_callbacks.rb +46 -0
  71. data/lib/scaffold/lib/model/relations/relation.rb +151 -0
  72. data/lib/scaffold/lib/model/relations/searchable.rb +27 -0
  73. data/lib/scaffold/lib/model/validations/validations.rb +31 -0
  74. data/lib/scaffold/lib/model/validations/validator.rb +81 -0
  75. data/lib/scaffold/lib/router/route.rb +24 -0
  76. data/lib/scaffold/lib/router/router.rb +192 -0
  77. data/lib/scaffold/lib/utils/url_helpers.rb +96 -0
  78. data/lib/scaffold/public/main.css +165 -0
  79. data/rails_lite.gemspec +41 -0
  80. metadata +168 -0
@@ -0,0 +1,27 @@
1
+ module Searchable
2
+
3
+ def where(params)
4
+ relation = Relation.new(table_name: self.table_name)
5
+ relation.where(params)
6
+ end
7
+
8
+ def joins(table_name)
9
+ relation = Relation.new(table_name: self.table_name)
10
+ relation.joins(table_name)
11
+ end
12
+
13
+ def left_joins(table_name)
14
+ relation = Relation.new(table_name: self.table_name)
15
+ relation.left_joins(table_name)
16
+ end
17
+
18
+ def select(*params)
19
+ relation = Relation.new(table_name: self.table_name)
20
+ relation.select(*params)
21
+ end
22
+
23
+ def find_by(params)
24
+ arr = where(params)
25
+ arr.empty? ? nil : arr.first
26
+ end
27
+ end
@@ -0,0 +1,31 @@
1
+ require 'active_support/concern'
2
+ require_relative 'validator'
3
+
4
+ module Validations
5
+ extend ActiveSupport::Concern
6
+
7
+ def valid?
8
+ before_valid
9
+ self.class.validators.all? { |validator| validator.valid?(self) }
10
+ end
11
+
12
+ def errors
13
+ errors_array = []
14
+ self.class.validators.each do |validator|
15
+ errors_array += validator.errors(self)
16
+ end
17
+
18
+ errors_array
19
+ end
20
+
21
+ module ClassMethods
22
+
23
+ def validators
24
+ @validators ||= []
25
+ end
26
+
27
+ def validates(attribute, options = {})
28
+ validators << Validator.new(attribute, options)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,81 @@
1
+ class Validator
2
+ attr_reader :options, :attribute
3
+
4
+ def initialize(attribute, options = {})
5
+ default = {
6
+ allow_nil: false,
7
+ presence: false,
8
+ uniqueness: false,
9
+ length: false,
10
+ class: false
11
+ }
12
+
13
+ default.merge!(options)
14
+ @attribute = attribute
15
+ @options = default
16
+ end
17
+
18
+ def allow_nil(_obj, _val, _errors_array)
19
+ end
20
+
21
+ def presence(_obj, val, errors_array)
22
+ errors_array << "#{attribute} must be present" if val.blank?
23
+ end
24
+
25
+ def uniqueness(obj, val, errors_array)
26
+ if obj.id.nil?
27
+ where_line = "#{attribute} = '#{val}'"
28
+ else
29
+ where_line = "#{attribute} = '#{val}' AND id != #{obj.id}"
30
+ end
31
+
32
+ arr = obj.class.where(where_line)
33
+ errors_array << "#{attribute} must be unique" unless arr.empty?
34
+ end
35
+
36
+ def class(_obj, val, errors_array)
37
+ errors_array << "#{attribute} must be #{options[:class]}" unless val.is_a?(options[:class])
38
+ end
39
+
40
+ def length(_obj, val, errors_array)
41
+ if val.nil?
42
+ errors_array << "#{attribute} can't be nil" unless options[:length][:allow_nil]
43
+
44
+ return errors_array
45
+ elsif options[:length].is_a?(Hash)
46
+
47
+ min = options[:length][:minimum]
48
+ if min && val.length < min
49
+ errors_array << "#{attribute} must be longer than #{min} characters"
50
+ end
51
+
52
+ max = options[:length][:maximum]
53
+ if max && val.length > max
54
+ errors_array << "#{attribute} must be shorter than #{max} characters"
55
+ end
56
+ else
57
+ unless val.length = options[:length]
58
+ errors_array << "#{attribute} must be #{max} characters"
59
+ end
60
+ end
61
+
62
+ errors_array
63
+ end
64
+
65
+ def valid?(obj)
66
+ errors(obj).empty?
67
+ end
68
+
69
+ def errors(obj)
70
+ errors_array = []
71
+ val = obj.send(attribute)
72
+
73
+ return errors_array if val.nil? && options[:allow_nil]
74
+
75
+ options.each do |name, validate|
76
+ self.send(name, obj, val, errors_array) if validate
77
+ end
78
+
79
+ errors_array
80
+ end
81
+ end
@@ -0,0 +1,24 @@
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, @http_method, @controller_class, @action_name = pattern, http_method, controller_class, action_name
6
+ end
7
+
8
+ def matches?(req)
9
+ method = req.params['_method'] || req.request_method
10
+ pattern =~ req.path && http_method.to_s == method.downcase
11
+ end
12
+
13
+ def run(req, res, patterns)
14
+ route_params = {}
15
+ match_data = pattern.match(req.path)
16
+
17
+ match_data.names.each do |key|
18
+ route_params[key] = match_data[key]
19
+ end
20
+
21
+ controller = controller_class.new(req, res, route_params, patterns)
22
+ controller.invoke_action(action_name)
23
+ end
24
+ end
@@ -0,0 +1,192 @@
1
+ require_relative 'route'
2
+ require_relative '../utils/url_helpers'
3
+
4
+ class Router
5
+ include UrlHelpers
6
+ attr_reader :routes, :patterns
7
+
8
+ def initialize
9
+ @routes = []
10
+ @patterns = []
11
+ @current_route = "^/"
12
+ @member_route = "^/"
13
+ @collection_route = "^/"
14
+ @nested_route = "^/"
15
+ @current_class = nil;
16
+ end
17
+
18
+ def display_routes
19
+ routes.each do |route|
20
+ url = Router.make_url(route.pattern)
21
+ method = route.http_method
22
+ controller = route.controller_class
23
+ helper = Router.make_helper_name(route.pattern)
24
+ action = route.action_name
25
+
26
+ puts "#{method.to_s.upcase}: #{url}, #{controller}##{action}, #{helper}"
27
+ end
28
+ end
29
+
30
+ def add_route(pattern, method, controller_class, action_name)
31
+ routes << Route.new(pattern, method, controller_class, action_name)
32
+ patterns << pattern unless patterns.include?(pattern)
33
+ end
34
+
35
+ def draw(&proc)
36
+ self.instance_eval(&proc)
37
+ end
38
+
39
+ [:get, :post, :patch, :delete, :put].each do |http_method|
40
+ define_method(http_method) do |name, options = {}|
41
+ default = { to: "#{current_class}##{name}" }
42
+ default.merge!(options)
43
+
44
+ if name.is_a?(Symbol)
45
+ pattern = Regexp.new("#{current_route}#{name}/?$")
46
+ elsif name.is_a?(String)
47
+ url_arr = Router.make_url_arr_from_path(name)
48
+ url_arr.map! do |str|
49
+ if str[0] === ":"
50
+ "(?<#{str[1..-1]}>\\d+)"
51
+ else
52
+ str
53
+ end
54
+ end
55
+
56
+ path = url_arr.join("/")
57
+ pattern = Regexp.new("^/#{path}/?$")
58
+ end
59
+
60
+ to_array = default[:to].split('#')
61
+ controller_class = "#{to_array[0].capitalize}Controller".constantize
62
+ action_name = to_array[1].to_sym
63
+ add_route(pattern, http_method, controller_class, action_name)
64
+ end
65
+ end
66
+
67
+ def match(req)
68
+ routes.find { |route| route.matches?(req) }
69
+ end
70
+
71
+ def resources(name, options = {}, &prc)
72
+ controller_class = "#{name.capitalize}Controller".constantize
73
+ methods = [:index, :create, :new, :edit, :update, :show, :destroy]
74
+ patterns = {
75
+ index: [Regexp.new("#{current_route}#{name}/?$"), :get],
76
+ new: [Regexp.new("#{current_route}#{name}/new/?$"), :get],
77
+ show: [Regexp.new("#{current_route}#{name}/(?<id>\\d+)/?$"), :get],
78
+ create: [Regexp.new("#{current_route}#{name}$"), :post],
79
+ destroy: [Regexp.new("#{current_route}#{name}/(?<id>\\d+)/?$"), :delete],
80
+ update: [Regexp.new("#{current_route}#{name}/(?<id>\\d+)/?$"), :patch],
81
+ edit: [Regexp.new("#{current_route}#{name}/(?<id>\\d+)/edit/?$"), :get]
82
+ }
83
+
84
+ default = { only: methods, except: [] }
85
+ default.merge!(options)
86
+ names = default[:only] - default[:except]
87
+
88
+ names.each do |name|
89
+ params = patterns[name] + [controller_class] + [name]
90
+ add_route(*params)
91
+ end
92
+
93
+ self.current_class = name
94
+ set_resources_routes(name)
95
+ prc.call if prc
96
+ reset_routes
97
+
98
+ nil
99
+ end
100
+
101
+ def resource(name, options = {}, &prc)
102
+ controller_class = "#{name.capitalize}Controller".constantize
103
+ methods = [:index, :create, :new, :edit, :update, :show, :destroy]
104
+ patterns = {
105
+ index: [Regexp.new("#{current_route}#{name}/?$"), :get],
106
+ new: [Regexp.new("#{current_route}#{name}/new/?$"), :get],
107
+ show: [Regexp.new("#{current_route}#{name}/?$"), :get],
108
+ create: [Regexp.new("#{current_route}#{name}$"), :post],
109
+ destroy: [Regexp.new("#{current_route}#{name}/?$"), :delete],
110
+ update: [Regexp.new("#{current_route}#{name}/?$"), :patch],
111
+ edit: [Regexp.new("#{current_route}#{name}/edit/?$"), :get]
112
+ }
113
+
114
+ default = { only: methods, except: [] }
115
+ default.merge!(options)
116
+ names = default[:only] - default[:except]
117
+
118
+ names.each do |name|
119
+ params = patterns[name] + [controller_class] + [name]
120
+ add_route(*params)
121
+ end
122
+
123
+ self.current_class = name
124
+ set_resource_routes(name)
125
+ prc.call if prc
126
+ reset_routes
127
+
128
+ nil
129
+ end
130
+
131
+ def member(&prc)
132
+ self.current_route = member_route
133
+ prc.call if prc
134
+ self.current_route = nested_route
135
+
136
+ nil
137
+ end
138
+
139
+ def collection(&prc)
140
+ self.current_route = collection_route
141
+ prc.call if prc
142
+ self.current_route = nested_route
143
+
144
+ nil
145
+ end
146
+
147
+ def root(options = {})
148
+ to_array = options[:to].split('#')
149
+ pattern = Regexp.new("^/?$")
150
+ http_method = :get
151
+ controller_class = "#{to_array[0].capitalize}Controller".constantize
152
+ action_name = to_array[1].to_sym
153
+
154
+ add_route(pattern, http_method, controller_class, action_name)
155
+ end
156
+
157
+ def run(req, res)
158
+ route = match(req)
159
+ if route
160
+ route.run(req, res, patterns)
161
+ else
162
+ res.status = 404
163
+ res.write('Route not found')
164
+ end
165
+ end
166
+
167
+ private
168
+ attr_accessor :current_route, :member_route, :collection_route,
169
+ :nested_route, :current_class
170
+
171
+ def set_resources_routes(name)
172
+ self.member_route = current_route + "#{name}/(?<id>\\d+)/"
173
+ self.collection_route = current_route + "#{name}/"
174
+ self.nested_route = current_route + "#{name}/(?<#{name.to_s.singularize}_id>\\d+)/"
175
+ self.current_route = nested_route
176
+ end
177
+
178
+ def set_resource_routes(name)
179
+ self.member_route = current_route + "#{name}/"
180
+ self.collection_route = current_route + "#{name}/"
181
+ self.nested_route = current_route + "#{name}/"
182
+ self.current_route = nested_route
183
+ end
184
+
185
+ def reset_routes
186
+ self.current_route = "^/"
187
+ self.member_route = "^/"
188
+ self.collection_route = "^/"
189
+ self.nested_route = "^/"
190
+ self.current_class = nil
191
+ end
192
+ end
@@ -0,0 +1,96 @@
1
+ require 'active_support/concern'
2
+
3
+ module UrlHelpers
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+
8
+ def make_url_arr(pattern)
9
+ pattern.inspect.delete('\^$?<>/+()')
10
+ .split('\\').drop(1).reject { |el| el == "d"}
11
+ end
12
+
13
+ def make_url_arr_from_path(path)
14
+ path.split("/").drop(1)
15
+ end
16
+
17
+ def make_url(pattern)
18
+ "/" + make_url_arr(pattern).join("/")
19
+ end
20
+
21
+ def make_helpers(patterns)
22
+ patterns.each do |pattern|
23
+ url_arr = make_url_arr(pattern)
24
+ if url_arr.include?("id") || url_arr.any? { |str| str.include?("_id") }
25
+ make_id_helpers(url_arr)
26
+ else
27
+ make_idless_helpers(url_arr)
28
+ end
29
+ end
30
+ end
31
+
32
+ def make_helper_name(pattern)
33
+ url_arr = make_url_arr(pattern)
34
+ return "root_url" if url_arr.empty?
35
+
36
+ if url_arr.include?("id") || url_arr.any? { |str| str.include?("_id") }
37
+ make_id_helper_name(url_arr)
38
+ else
39
+ make_idless_helper_name(url_arr)
40
+ end
41
+ end
42
+
43
+ def make_id_helper_name(url_arr)
44
+ name_arr = url_arr.dup
45
+ name_arr[0] = url_arr.first.singularize
46
+ filtered_arr = name_arr.reject do |el|
47
+ el == "id" || el.include?("_id")
48
+ end
49
+
50
+ if filtered_arr.last == "edit" || filtered_arr.last == "new"
51
+ filtered_arr.unshift(filtered_arr.pop)
52
+ end
53
+
54
+ filtered_arr.join("_") + "_url"
55
+ end
56
+
57
+ def make_idless_helper_name(url_arr)
58
+ url_arr = url_arr.dup
59
+ if url_arr.last == "edit" || url_arr.last == "new"
60
+ url_arr.unshift(url_arr.pop)
61
+ end
62
+
63
+ url_arr.join("_") + "_url"
64
+ end
65
+
66
+ private
67
+
68
+ def make_idless_helpers(url_arr)
69
+ helper_name = make_idless_helper_name(url_arr)
70
+ url = "/" + url_arr.join("/")
71
+
72
+ define_method(helper_name) do
73
+ url
74
+ end
75
+ end
76
+
77
+ def make_id_helpers(url_arr)
78
+ helper_name = make_id_helper_name(url_arr)
79
+
80
+ define_method(helper_name) do |*ids|
81
+ url = url_arr.map do |el|
82
+ if el == "id" || el.include?("_id")
83
+ id = ids.pop
84
+ obj_id = id.try(:id)
85
+
86
+ "#{obj_id || id}"
87
+ else
88
+ el
89
+ end
90
+ end
91
+
92
+ "/" + url.join("/")
93
+ end
94
+ end
95
+ end
96
+ end