ru.Bee 1.3.1 → 1.3.3
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.
- checksums.yaml +4 -4
- data/bin/rubee +80 -86
- data/lib/config/base_configuration.rb +6 -6
- data/lib/config/routes.rb +1 -1
- data/lib/db/create_accounts.rb +8 -8
- data/lib/db/create_comments.rb +7 -7
- data/lib/db/create_posts.rb +8 -8
- data/lib/db/create_users.rb +8 -8
- data/lib/db/structure.rb +42 -42
- data/lib/inits/print_colors.rb +1 -1
- data/lib/rubee/async/asyncable.rb +2 -2
- data/lib/rubee/async/sidekiq_async.rb +11 -11
- data/lib/rubee/async/thread_async.rb +1 -1
- data/lib/rubee/async/thread_pool.rb +2 -2
- data/lib/rubee/controllers/base_controller.rb +30 -21
- data/lib/rubee/controllers/extensions/auth_tokenable.rb +10 -8
- data/lib/rubee/controllers/extensions/middlewarable.rb +1 -1
- data/lib/rubee/controllers/middlewares/auth_token_middleware.rb +12 -8
- data/lib/rubee/extensions/hookable.rb +3 -6
- data/lib/rubee/extensions/serializable.rb +3 -3
- data/lib/rubee/models/database_objectable.rb +11 -12
- data/lib/rubee/models/sequel_object.rb +31 -24
- data/lib/rubee.rb +54 -42
- data/lib/tests/account_model_test.rb +4 -4
- data/lib/tests/auth_tokenable_test.rb +6 -6
- data/lib/tests/comment_model_test.rb +7 -7
- data/lib/tests/example_models/account.rb +1 -0
- data/lib/tests/example_models/comment.rb +1 -0
- data/lib/tests/example_models/post.rb +1 -0
- data/lib/tests/example_models/user.rb +1 -0
- data/lib/tests/rubeeapp_test.rb +5 -7
- data/lib/tests/test.db +0 -0
- data/lib/tests/test_helper.rb +3 -5
- data/lib/tests/user_model_test.rb +70 -54
- data/readme.md +7 -4
- metadata +2 -2
@@ -1,15 +1,15 @@
|
|
1
1
|
module Rubee
|
2
|
-
class SidekiqAsync
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
2
|
+
class SidekiqAsync
|
3
|
+
def perform_async(**args)
|
4
|
+
options = if args[:options].is_a?(Hash)
|
5
|
+
[JSON.generate(args[:options])]
|
6
|
+
elsif args[:options].is_a?(Array)
|
7
|
+
args[:options]
|
8
|
+
else
|
9
|
+
[args[:options]]
|
10
|
+
end
|
11
11
|
|
12
|
-
|
12
|
+
args[:_class].perform_async(*options)
|
13
|
+
end
|
13
14
|
end
|
14
15
|
end
|
15
|
-
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Rubee
|
2
2
|
class ThreadAsync
|
3
3
|
def perform_async(**args)
|
4
|
-
color_puts
|
4
|
+
color_puts('WARN: ThreadAsync engine is not yet recommended for production', color: :yellow)
|
5
5
|
ThreadPool.instance.enqueue(args[:_class], args[:options])
|
6
6
|
end
|
7
7
|
end
|
@@ -23,7 +23,7 @@ module Rubee
|
|
23
23
|
|
24
24
|
def shutdown
|
25
25
|
@running = false
|
26
|
-
THREADS_LIMIT.times { @queue << { task:
|
26
|
+
THREADS_LIMIT.times { @queue << { task: :stop, args: nil } }
|
27
27
|
@workers.each(&:join)
|
28
28
|
end
|
29
29
|
|
@@ -39,6 +39,7 @@ module Rubee
|
|
39
39
|
args = task_hash[:args]
|
40
40
|
end
|
41
41
|
break if task == :stop
|
42
|
+
|
42
43
|
begin
|
43
44
|
task.new.perform(**args)
|
44
45
|
rescue StandardError => e
|
@@ -50,4 +51,3 @@ module Rubee
|
|
50
51
|
end
|
51
52
|
end
|
52
53
|
end
|
53
|
-
|
@@ -12,37 +12,38 @@ module Rubee
|
|
12
12
|
|
13
13
|
if File.exist?(image_path) && File.file?(image_path)
|
14
14
|
mime_type = Rack::Mime.mime_type(File.extname(image_path))
|
15
|
-
response_with
|
15
|
+
response_with(object: File.read(image_path), type: :image, mime_type: mime_type)
|
16
16
|
else
|
17
|
-
response_with
|
17
|
+
response_with(object: 'Image not found', type: :text)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
def response_with type: nil, object: nil, status: 200, mime_type: nil, render_view: nil, headers: {}, to: nil,
|
21
|
+
def response_with type: nil, object: nil, status: 200, mime_type: nil, render_view: nil, headers: {}, to: nil,
|
22
|
+
file: nil, filename: nil, **options
|
22
23
|
case type&.to_sym
|
23
24
|
in :json
|
24
25
|
rendered_json = object.is_a?(Array) ? object&.map(&:to_h).to_json : object.to_json
|
25
|
-
|
26
|
+
[status, headers.merge('content-type' => 'application/json'), [rendered_json]]
|
26
27
|
in :image
|
27
|
-
|
28
|
+
[status, headers.merge('content-type' => mime_type), [object]]
|
28
29
|
in :file
|
29
|
-
|
30
|
+
[
|
30
31
|
status,
|
31
32
|
headers.merge(
|
32
|
-
|
33
|
-
|
33
|
+
'content-disposition' => "attachment; filename=#{filename}",
|
34
|
+
'content-type' => 'application/octet-stream'
|
34
35
|
),
|
35
|
-
file
|
36
|
+
file,
|
36
37
|
]
|
37
38
|
in :text
|
38
|
-
|
39
|
+
[status, headers.merge('content-type' => 'text/plain'), [object.to_s]]
|
39
40
|
in :unauthentificated
|
40
|
-
|
41
|
+
[401, headers.merge('content-type' => 'text/plain'), ['Unauthentificated']]
|
41
42
|
in :redirect
|
42
|
-
|
43
|
+
[302, headers.merge('location' => to.to_s), ['Unauthentificated']]
|
43
44
|
else # rendering erb view is a default behavior
|
44
|
-
view_file_name = self.class.name.split(
|
45
|
-
erb_file = render_view ?
|
45
|
+
view_file_name = self.class.name.split('Controller').first.downcase
|
46
|
+
erb_file = render_view ? render_view.to_s : "#{view_file_name}_#{@route[:action]}"
|
46
47
|
lib = Rubee::PROJECT_NAME == 'rubee' ? 'lib/' : ''
|
47
48
|
view = render_template(erb_file, { object:, **(options[:locals] || {}) })
|
48
49
|
|
@@ -55,7 +56,7 @@ module Rubee
|
|
55
56
|
ERB.new(view).result(binding)
|
56
57
|
end
|
57
58
|
|
58
|
-
|
59
|
+
[status, headers.merge('content-type' => 'text/html'), [whole_erb]]
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
@@ -69,25 +70,33 @@ module Rubee
|
|
69
70
|
|
70
71
|
def params
|
71
72
|
inputs = @request.env['rack.input'].read
|
72
|
-
body =
|
73
|
-
|
73
|
+
body = begin
|
74
|
+
JSON.parse(@request.body.read.strip)
|
75
|
+
rescue StandardError
|
76
|
+
{}
|
77
|
+
end
|
78
|
+
begin
|
79
|
+
body.merge!(URI.decode_www_form(inputs).to_h.transform_keys(&:to_sym))
|
80
|
+
rescue StandardError
|
81
|
+
nil
|
82
|
+
end
|
74
83
|
@params ||= extract_params(@request.path, @route[:path])
|
75
84
|
.merge(body)
|
76
85
|
.merge(@request.params)
|
77
86
|
.transform_keys(&:to_sym)
|
78
|
-
.
|
87
|
+
.reject { |k, _v| [:_method].include?(k.downcase.to_sym) }
|
79
88
|
end
|
80
89
|
|
81
90
|
def headers
|
82
|
-
@request.env.select {|k,
|
83
|
-
.collect {|key, val| [key.sub(/^HTTP_/, ''), val]}
|
91
|
+
@request.env.select { |k, _v| k.start_with?('HTTP_') }
|
92
|
+
.collect { |key, val| [key.sub(/^HTTP_/, ''), val] }
|
84
93
|
end
|
85
94
|
|
86
95
|
def extract_params(path, pattern)
|
87
96
|
regex_pattern = pattern.gsub(/\{(\w+)\}/, '(?<\1>[^/]+)')
|
88
97
|
regex = Regexp.new("^#{regex_pattern}$")
|
89
98
|
|
90
|
-
if match = path.match(regex)
|
99
|
+
if (match = path.match(regex))
|
91
100
|
return match.named_captures&.transform_keys(&:to_sym)
|
92
101
|
end
|
93
102
|
|
@@ -18,37 +18,39 @@ module Rubee
|
|
18
18
|
def authentificated?
|
19
19
|
methods = self.class._auth_methods
|
20
20
|
return true if methods && !methods.include?(@route[:action].to_sym)
|
21
|
+
|
21
22
|
# This is suppose to be set in the middleware, otherwise it will return false
|
22
23
|
valid_token?
|
23
24
|
end
|
24
25
|
|
25
26
|
def valid_token?
|
26
|
-
@request.env[
|
27
|
+
@request.env['rack.session']&.[]('authentificated')
|
27
28
|
end
|
28
29
|
|
29
30
|
def authentificated_user
|
30
31
|
# User model must be created with email and password properties at least
|
31
|
-
@
|
32
|
+
@authentificated_user ||= User.where(email: params[:email], password: params[:password]).first
|
32
33
|
end
|
33
34
|
|
34
35
|
def authentificate!
|
35
36
|
return false unless authentificated_user
|
37
|
+
|
36
38
|
# Generate token
|
37
39
|
payload = { username: params[:email], exp: Time.now.to_i + EXPIRE }
|
38
40
|
@token = JWT.encode(payload, KEY, 'HS256')
|
39
41
|
# Set jwt token to the browser within cookie, so next browser request will include it.
|
40
42
|
# make sure it passed to response_with headers options
|
41
|
-
@token_header = {
|
43
|
+
@token_header = { 'set-cookie' => "jwt=#{@token}; path=/; httponly; secure" }
|
42
44
|
|
43
45
|
true
|
44
46
|
end
|
45
47
|
|
46
48
|
def unauthentificate!
|
47
|
-
@request.env[
|
49
|
+
@request.env['rack.session']['authentificated'] = nil if @request.env['rack.session']&.[]('authentificated')
|
48
50
|
@authehtificated_user = nil if @authehtificated_user
|
49
51
|
@zeroed_token_header = {
|
50
|
-
|
51
|
-
|
52
|
+
'set-cookie' => 'jwt=; path=/; httponly; secure; expires=thu, 01 jan 1970 00:00:00 gmt',
|
53
|
+
'content-type' => 'application/json',
|
52
54
|
}
|
53
55
|
|
54
56
|
true
|
@@ -58,7 +60,7 @@ module Rubee
|
|
58
60
|
if authentificated?
|
59
61
|
yield
|
60
62
|
else
|
61
|
-
response_with
|
63
|
+
response_with(type: :unauthentificated)
|
62
64
|
end
|
63
65
|
end
|
64
66
|
end
|
@@ -69,7 +71,7 @@ module Rubee
|
|
69
71
|
@auth_methods.concat(args.map(&:to_sym)).uniq!
|
70
72
|
|
71
73
|
@auth_methods.each do |method|
|
72
|
-
around
|
74
|
+
around(method, :handle_auth)
|
73
75
|
end
|
74
76
|
end
|
75
77
|
|
@@ -9,7 +9,7 @@ module Middlewarable
|
|
9
9
|
|
10
10
|
module Initializer
|
11
11
|
def initialize(req, route)
|
12
|
-
app = ->(
|
12
|
+
app = ->(_env) { super(req, route) }
|
13
13
|
self.class.middlewares.reverse_each do |middleware|
|
14
14
|
middleware_class = Object.const_get(middleware)
|
15
15
|
app = middleware_class.new(app, req)
|
@@ -7,13 +7,13 @@ module Rubee
|
|
7
7
|
|
8
8
|
def call(env)
|
9
9
|
# get token from header
|
10
|
-
auth_header = headers(env)[
|
11
|
-
token = auth_header ? auth_header[/^Bearer (.*)$/]&.gsub(
|
10
|
+
auth_header = headers(env)['HTTP_AUTHORIZATION']
|
11
|
+
token = auth_header ? auth_header[/^Bearer (.*)$/]&.gsub('Bearer ', '') : nil
|
12
12
|
# get token from cookies
|
13
|
-
token
|
13
|
+
token ||= @req.cookies['jwt']
|
14
14
|
if valid_token?(token)
|
15
|
-
env[
|
16
|
-
env[
|
15
|
+
env['rack.session'] ||= {}
|
16
|
+
env['rack.session']['authentificated'] = true
|
17
17
|
end
|
18
18
|
|
19
19
|
@app.call(env)
|
@@ -22,7 +22,7 @@ module Rubee
|
|
22
22
|
private
|
23
23
|
|
24
24
|
def headers(env)
|
25
|
-
env.each_with_object({}) { |(k, v), h| h[k] = v if k.start_with?(
|
25
|
+
env.each_with_object({}) { |(k, v), h| h[k] = v if k.start_with?('HTTP_') }
|
26
26
|
end
|
27
27
|
|
28
28
|
def valid_token?(token)
|
@@ -35,8 +35,12 @@ module Rubee
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def decode_jwt(token)
|
38
|
-
decoded_array =
|
39
|
-
|
38
|
+
decoded_array = begin
|
39
|
+
JWT.decode(token, AuthTokenable::KEY, true, { algorithm: 'HS256' })
|
40
|
+
rescue StandardError
|
41
|
+
[]
|
42
|
+
end
|
43
|
+
decoded_array&.first&.transform_keys(&:to_sym) || {} # Extract payload
|
40
44
|
end
|
41
45
|
end
|
42
46
|
end
|
@@ -16,7 +16,7 @@ module Rubee
|
|
16
16
|
super(*args, &block)
|
17
17
|
end
|
18
18
|
end
|
19
|
-
prepend
|
19
|
+
prepend(hooks)
|
20
20
|
end
|
21
21
|
|
22
22
|
def after(method, handler, **options)
|
@@ -31,7 +31,7 @@ module Rubee
|
|
31
31
|
result
|
32
32
|
end
|
33
33
|
end
|
34
|
-
prepend
|
34
|
+
prepend(hooks)
|
35
35
|
end
|
36
36
|
|
37
37
|
def around(method, handler, **options)
|
@@ -48,7 +48,7 @@ module Rubee
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
51
|
-
prepend
|
51
|
+
prepend(hooks)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -58,7 +58,6 @@ module Rubee
|
|
58
58
|
def conditions_met?(if_condition = nil, unless_condition = nil)
|
59
59
|
return true if if_condition.nil? && unless_condition.nil?
|
60
60
|
|
61
|
-
if_condition_result = true
|
62
61
|
if_condition_result =
|
63
62
|
if if_condition.nil?
|
64
63
|
true
|
@@ -67,8 +66,6 @@ module Rubee
|
|
67
66
|
elsif respond_to?(if_condition)
|
68
67
|
send(if_condition)
|
69
68
|
end
|
70
|
-
|
71
|
-
unless_condition_result = true
|
72
69
|
unless_condition_result =
|
73
70
|
if unless_condition.nil?
|
74
71
|
false
|
@@ -8,19 +8,19 @@ module Rubee
|
|
8
8
|
module Initializer
|
9
9
|
def initialize(attrs)
|
10
10
|
attrs.each do |attr, value|
|
11
|
-
|
11
|
+
send("#{attr}=", value)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
module InstanceMethods
|
17
|
-
def to_json
|
17
|
+
def to_json(*_args)
|
18
18
|
to_h.to_json
|
19
19
|
end
|
20
20
|
|
21
21
|
def to_h
|
22
22
|
instance_variables.each_with_object({}) do |var, hash|
|
23
|
-
hash[var.to_s.delete(
|
23
|
+
hash[var.to_s.delete('@')] = instance_variable_get(var)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -1,32 +1,32 @@
|
|
1
1
|
module Rubee
|
2
2
|
module DatabaseObjectable
|
3
3
|
def self.included(base)
|
4
|
-
base.extend
|
5
|
-
base.include
|
6
|
-
base.prepend
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
base.include(InstanceMethods)
|
6
|
+
base.prepend(Initializer)
|
7
7
|
|
8
|
-
base.include
|
9
|
-
base.include
|
8
|
+
base.include(Rubee::Hookable)
|
9
|
+
base.include(Rubee::Serializable)
|
10
10
|
end
|
11
11
|
|
12
12
|
module ClassMethods
|
13
13
|
def pluralize_class_name
|
14
|
-
pluralize(
|
14
|
+
pluralize(name.downcase)
|
15
15
|
end
|
16
16
|
|
17
17
|
def pluralize(word)
|
18
18
|
if word.end_with?('y') && !%w[a e i o u].include?(word[-2])
|
19
|
-
word[0..-2]
|
19
|
+
"#{word[0..-2]}ies" # Replace "y" with "ies"
|
20
20
|
elsif word.end_with?('s', 'x', 'z', 'ch', 'sh')
|
21
|
-
word
|
21
|
+
"#{word}es" # Add "es" for certain endings
|
22
22
|
else
|
23
|
-
word
|
23
|
+
"#{word}s" # Default to adding "s"
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
def singularize(word)
|
28
28
|
if word.end_with?('ies') && word.length > 3
|
29
|
-
word[0..-4]
|
29
|
+
"#{word[0..-4]}y" # Convert "ies" to "y"
|
30
30
|
elsif word.end_with?('es') && %w[s x z ch sh].any? { |ending| word[-(ending.length + 2)..-3] == ending }
|
31
31
|
word[0..-3] # Remove "es" for words like "foxes", "buses"
|
32
32
|
elsif word.end_with?('s') && word.length > 1
|
@@ -38,7 +38,7 @@ module Rubee
|
|
38
38
|
|
39
39
|
def accessor_names
|
40
40
|
instance_methods(false)
|
41
|
-
.select { |m| method_defined?("#{m}=") }
|
41
|
+
.select { |m| method_defined?("#{m}=") } # Check if setter exists
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -49,4 +49,3 @@ module Rubee
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
52
|
-
|
@@ -2,7 +2,7 @@ module Rubee
|
|
2
2
|
class SequelObject
|
3
3
|
include Rubee::DatabaseObjectable
|
4
4
|
|
5
|
-
def destroy(cascade: false, **
|
5
|
+
def destroy(cascade: false, **_options)
|
6
6
|
if cascade
|
7
7
|
# find all tables with foreign key
|
8
8
|
tables_with_fk = DB.tables.select do |table|
|
@@ -21,20 +21,27 @@ module Rubee
|
|
21
21
|
def save
|
22
22
|
args = to_h.dup&.transform_keys(&:to_sym)
|
23
23
|
if args[:id]
|
24
|
-
|
24
|
+
begin
|
25
|
+
udpate(args)
|
26
|
+
rescue StandardError => _e
|
27
|
+
return false
|
28
|
+
end
|
25
29
|
|
26
|
-
true
|
27
30
|
else
|
28
|
-
|
31
|
+
begin
|
32
|
+
created_object = self.class.create(args)
|
33
|
+
rescue StandardError => _e
|
34
|
+
return false
|
35
|
+
end
|
29
36
|
self.id = created_object.id
|
30
37
|
|
31
|
-
true
|
32
38
|
end
|
39
|
+
true
|
33
40
|
end
|
34
41
|
|
35
|
-
def assign_attributes(args={})
|
36
|
-
to_h.
|
37
|
-
|
42
|
+
def assign_attributes(args = {})
|
43
|
+
to_h.each_key do |attr|
|
44
|
+
send("#{attr}=", args[attr.to_sym]) if args[attr.to_sym]
|
38
45
|
end
|
39
46
|
end
|
40
47
|
|
@@ -57,14 +64,14 @@ module Rubee
|
|
57
64
|
class << self
|
58
65
|
def last
|
59
66
|
found_hash = dataset.order(:id).last
|
60
|
-
return
|
67
|
+
return new(**found_hash) if found_hash
|
61
68
|
|
62
69
|
nil
|
63
70
|
end
|
64
71
|
|
65
72
|
def first
|
66
73
|
found_hash = dataset.order(:id).first
|
67
|
-
return
|
74
|
+
return new(**found_hash) if found_hash
|
68
75
|
|
69
76
|
nil
|
70
77
|
end
|
@@ -73,9 +80,9 @@ module Rubee
|
|
73
80
|
# owns_many :comments
|
74
81
|
# > user.comments
|
75
82
|
# > [<comment1>, <comment2>]
|
76
|
-
def owns_many(assoc, fk_name: nil, over: nil, **
|
83
|
+
def owns_many(assoc, fk_name: nil, over: nil, **_options)
|
77
84
|
singularized_assoc_name = singularize(assoc.to_s)
|
78
|
-
fk_name ||= "#{
|
85
|
+
fk_name ||= "#{name.to_s.downcase}_id"
|
79
86
|
|
80
87
|
define_method(assoc) do
|
81
88
|
klass = Object.const_get(singularized_assoc_name.capitalize)
|
@@ -94,9 +101,9 @@ module Rubee
|
|
94
101
|
# owns_one :user
|
95
102
|
# > comment.user
|
96
103
|
# > <user>
|
97
|
-
def owns_one(assoc, options={})
|
104
|
+
def owns_one(assoc, options = {})
|
98
105
|
Sequel::Model.one_to_one(assoc, **options)
|
99
|
-
fk_name ||= "#{
|
106
|
+
fk_name ||= "#{name.to_s.downcase}_id"
|
100
107
|
define_method(assoc) do
|
101
108
|
Object.const_get(assoc.capitalize).where(fk_name.to_sym => id)&.first
|
102
109
|
end
|
@@ -106,11 +113,11 @@ module Rubee
|
|
106
113
|
# holds :user
|
107
114
|
# > account.user
|
108
115
|
# > <user>
|
109
|
-
def holds(assoc, fk_name: nil, **
|
116
|
+
def holds(assoc, fk_name: nil, **_options)
|
110
117
|
fk_name ||= "#{assoc.to_s.downcase}_id"
|
111
118
|
define_method(assoc) do
|
112
119
|
target_klass = Object.const_get(assoc.capitalize)
|
113
|
-
target_klass.find(
|
120
|
+
target_klass.find(send(fk_name))
|
114
121
|
end
|
115
122
|
end
|
116
123
|
|
@@ -122,33 +129,33 @@ module Rubee
|
|
122
129
|
|
123
130
|
def dataset
|
124
131
|
@dataset ||= DB[pluralize_class_name.to_sym]
|
125
|
-
rescue Exception =>
|
132
|
+
rescue Exception => _e
|
126
133
|
reconnect!
|
127
134
|
retry
|
128
135
|
end
|
129
136
|
|
130
137
|
def all
|
131
138
|
dataset.map do |record_hash|
|
132
|
-
|
139
|
+
new(**record_hash)
|
133
140
|
end
|
134
141
|
end
|
135
142
|
|
136
143
|
def find(id)
|
137
144
|
found_hash = dataset.where(id:)&.first
|
138
|
-
return
|
145
|
+
return new(**found_hash) if found_hash
|
139
146
|
|
140
147
|
nil
|
141
148
|
end
|
142
149
|
|
143
150
|
def where(args)
|
144
151
|
dataset.where(**args).map do |record_hash|
|
145
|
-
|
152
|
+
new(**record_hash)
|
146
153
|
end
|
147
154
|
end
|
148
155
|
|
149
156
|
def order(*args)
|
150
157
|
dataset.order(*args).map do |record_hash|
|
151
|
-
|
158
|
+
new(**record_hash)
|
152
159
|
end
|
153
160
|
end
|
154
161
|
|
@@ -158,18 +165,18 @@ module Rubee
|
|
158
165
|
|
159
166
|
def create(attrs)
|
160
167
|
out_id = dataset.insert(**attrs)
|
161
|
-
|
168
|
+
new(**attrs.merge(id: out_id))
|
162
169
|
end
|
163
170
|
|
164
171
|
def destroy_all(cascade: false)
|
165
|
-
all.each{ |record| record.destroy(cascade:) }
|
172
|
+
all.each { |record| record.destroy(cascade:) }
|
166
173
|
end
|
167
174
|
|
168
175
|
def serialize(suquel_dataset, klass = nil)
|
169
176
|
klass ||= self
|
170
177
|
suquel_dataset.map do |record_hash|
|
171
178
|
target_klass_fields = DB[pluralize(klass.name.downcase).to_sym].columns
|
172
|
-
klass_attributes = record_hash.filter{ target_klass_fields.include?
|
179
|
+
klass_attributes = record_hash.filter { target_klass_fields.include?(_1) }
|
173
180
|
klass.new(**klass_attributes)
|
174
181
|
end
|
175
182
|
end
|