restme 0.0.37 → 0.0.39

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b1c3586a14caa25fa15e0d7bcaf12547738e779d43e498c9241dbb198990cbb
4
- data.tar.gz: 5ded53d0db89650ebab2580d512912a5939998347367fb7414dbdd07ace50c3e
3
+ metadata.gz: 66521fd280c2f53800dfece67dc0167d10f25b76a2d435064fdaea3d37f9b260
4
+ data.tar.gz: 3e8f3889d228f4e051e3516d23fedb16dacea71393667c9acbf6b897f42c5e6f
5
5
  SHA512:
6
- metadata.gz: 982f4ca537611174ec4a2ef7a768c26e33869b5491fab6ad58ea09189fe21fa9d35875f580982ccbb392ebd13c3d0fa3c8b8d4c5777e4fa4245e80b2585e8520
7
- data.tar.gz: 179e7b1f1f7d6604498ac40265c9f0e187781f0432f559997959af21934ef92b46e72fdffb8cfb52ce072af91c7a36695c830a8ddf8822e9453e860fbaed7aa9
6
+ metadata.gz: c4f29154906b6b23c1d2b2f2b18aa3be16da6c1b6e9d0f0952360eea13c141e05c39a6eaee952d402685e94556a07f2063137cbdcbbabbf8b0046434795e5124
7
+ data.tar.gz: 58e3f792a2f85054f3a9ff88ab19bd70fd9ceb6c1a3f9308bbdf403b53a6dab56430bc6ddc9af47d83941ef48cc629e2b4d360b523136282b8f543ca9f996c08
data/.env.example ADDED
@@ -0,0 +1 @@
1
+ DATABASE_HOST=restme_postgres
data/.rubocop.yml CHANGED
@@ -1,8 +1,14 @@
1
1
  AllCops:
2
2
  TargetRubyVersion: 3.0
3
+ SuggestExtensions: false
4
+ NewCops: enable
3
5
 
4
6
  Style/StringLiterals:
5
7
  EnforcedStyle: double_quotes
6
8
 
7
9
  Style/StringLiteralsInInterpolation:
8
10
  EnforcedStyle: double_quotes
11
+
12
+ Metrics/BlockLength:
13
+ Exclude:
14
+ - spec/lib/restme_controller_spec.rb
data/README.md CHANGED
@@ -1,7 +1,5 @@
1
1
  # Restme
2
2
 
3
- ## ⚠️ Do not use this gem yet. In progress
4
-
5
3
  [![Gem Version](https://badge.fury.io/rb/restme.svg)](https://badge.fury.io/rb/restme)
6
4
 
7
5
  Adds support for new **Rails** controller actions such as pagination, filtering, sorting, and selecting specific model fields. Easily implement full CRUD functionality by importing Restme into your controller.
@@ -21,7 +19,7 @@ gem install restme
21
19
  OR
22
20
 
23
21
  ```bash
24
- gem 'restme', '~> 0.0.33'
22
+ gem 'restme'
25
23
  ```
26
24
 
27
25
  ## Usage
@@ -36,6 +34,7 @@ gem 'restme', '~> 0.0.33'
36
34
 
37
35
  ### Usage examples
38
36
 
37
+ Rails API project example here: https://github.com/everson-ever/restme-example/pull/1
39
38
 
40
39
  #### First of all
41
40
 
data/docker-compose.yml CHANGED
@@ -9,5 +9,25 @@ services:
9
9
  volumes:
10
10
  - .:/var/www/restme
11
11
  mem_limit: 1024mb
12
+ depends_on:
13
+ - restme_postgres
14
+ restme_postgres:
15
+ image: postgres:15.8-alpine
16
+ container_name: restme_postgres
17
+ volumes:
18
+ - postgres_db:/var/lib/postgresql/data
19
+ ports:
20
+ - "5432:5432"
21
+ mem_limit: 512mb
22
+ restart: unless-stopped
23
+ environment:
24
+ - POSTGRES_PASSWORD=postgres
25
+ - POSTGRES_USERNAME=postgres
26
+ healthcheck:
27
+ test: ["CMD-SHELL", "pg_isready -U postgres"]
28
+ interval: 5s
29
+ timeout: 5s
30
+ retries: 5
12
31
  volumes:
13
32
  app:
33
+ postgres_db:
@@ -12,9 +12,25 @@ module Restme
12
12
 
13
13
  def user_authorize
14
14
  return true unless restme_current_user
15
- return if super_authorize? || allowed_roles_actions[action_name.to_sym]&.include?(user_role.to_sym)
15
+ return authorize_errors unless authorize?
16
16
 
17
- render json: { message: "Action not allowed" }, status: :forbidden
17
+ true
18
+ end
19
+
20
+ def authorize?
21
+ super_authorize? ||
22
+ allowed_roles_actions[action_name.to_sym]&.include?(user_role.to_sym)
23
+ end
24
+
25
+ def authorize_errors
26
+ restme_scope_errors(
27
+ {
28
+ message: "Action not allowed",
29
+ body: {}
30
+ }
31
+ )
32
+
33
+ restme_scope_status(:forbidden)
18
34
  end
19
35
 
20
36
  def allowed_roles_actions
@@ -10,8 +10,6 @@ module Restme
10
10
  include Restme::Scope::Field::Attachable
11
11
 
12
12
  def fieldable_scope(user_scope)
13
- unallowed_select_fields_error
14
-
15
13
  return user_scope unless select_any_field?
16
14
 
17
15
  scoped = user_scope
@@ -72,12 +70,14 @@ module Restme
72
70
  end&.map(&:to_sym)
73
71
  end
74
72
 
75
- def unallowed_select_fields_error
73
+ def unallowed_select_fields_errors
76
74
  return if unallowed_fields_selected.blank?
77
75
 
78
76
  restme_scope_errors({ body: unallowed_fields_selected, message: "Selected not allowed fields" })
79
77
 
80
78
  restme_scope_status(:bad_request)
79
+
80
+ true
81
81
  end
82
82
 
83
83
  def unallowed_fields_selected
@@ -23,22 +23,37 @@ module Restme
23
23
 
24
24
  ID = :id
25
25
 
26
- FILTERS_TYPES = %i[equal like bigger_than less_than
27
- bigger_than_or_equal_to less_than_or_equal_to in].freeze
26
+ FILTERS_TYPES = %i[
27
+ equal
28
+ like
29
+ bigger_than
30
+ less_than
31
+ bigger_than_or_equal_to
32
+ less_than_or_equal_to
33
+ in
34
+ ].freeze
28
35
 
29
36
  private
30
37
 
31
38
  def filterable_scope(user_scope)
32
- return unallowed_filter_fields_response if unallowed_fields_to_filter?
39
+ @user_scope = user_scope
40
+
33
41
  return user_scope unless filterable_scope?
42
+ return user_scope if record_not_found_errors
43
+
44
+ processed_scope
45
+ end
34
46
 
35
- next_scope = where_equal(user_scope)
36
- next_scope = where_like(next_scope)
37
- next_scope = where_bigger_than(next_scope)
38
- next_scope = where_less_than(next_scope)
39
- next_scope = where_bigger_than_or_equal_to(next_scope)
40
- next_scope = where_less_than_or_equal_to(next_scope)
41
- where_in(next_scope)
47
+ def processed_scope
48
+ @processed_scope ||= begin
49
+ next_scope = where_equal(@user_scope)
50
+ next_scope = where_like(next_scope)
51
+ next_scope = where_bigger_than(next_scope)
52
+ next_scope = where_less_than(next_scope)
53
+ next_scope = where_bigger_than_or_equal_to(next_scope)
54
+ next_scope = where_less_than_or_equal_to(next_scope)
55
+ where_in(next_scope)
56
+ end
42
57
  end
43
58
 
44
59
  def allowed_fields
@@ -48,7 +63,6 @@ module Restme
48
63
  end
49
64
 
50
65
  record_field = param_key.to_s.gsub("_#{filter_type}", "")&.to_sym
51
-
52
66
  next unless filter_type
53
67
  next unless filteable_fields.include?(record_field)
54
68
 
@@ -66,29 +80,45 @@ module Restme
66
80
  [ID]
67
81
  end
68
82
 
69
- def unallowed_fields_to_filter?
70
- try_insert_id_equal
71
-
72
- filterable_scope? && unallowed_fields_to_filter.present?
73
- end
74
-
75
83
  def filterable_scope?
76
84
  request.get? && controller_params_filters_fields.present?
77
85
  end
78
86
 
79
- def unallowed_fields_to_filter
80
- @unallowed_fields_to_filter ||= controller_params_filters_fields - allowed_fields
81
- end
82
-
83
87
  def try_insert_id_equal
84
88
  return if params[:id].blank?
85
89
 
86
90
  controller_params_filters_fields.push(:id_equal)
87
91
  end
88
92
 
89
- def unallowed_filter_fields_response
90
- render json: { message: "Unknown Filter Fields", body: unallowed_fields_to_filter },
91
- status: :bad_request
93
+ def unallowed_filter_fields_errors
94
+ try_insert_id_equal
95
+
96
+ return unless unallowed_fields_to_filter.present?
97
+
98
+ restme_scope_errors(
99
+ {
100
+ message: "Unknown Filter Fields",
101
+ body: unallowed_fields_to_filter
102
+ }
103
+ )
104
+
105
+ restme_scope_status(:bad_request)
106
+
107
+ true
108
+ end
109
+
110
+ def record_not_found_errors
111
+ return if params[:id].blank? || processed_scope.exists?
112
+
113
+ restme_scope_errors({ body: { id: params[:id] }, message: "Record not found" })
114
+
115
+ restme_scope_status(:not_found)
116
+
117
+ true
118
+ end
119
+
120
+ def unallowed_fields_to_filter
121
+ @unallowed_fields_to_filter ||= controller_params_filters_fields - allowed_fields
92
122
  end
93
123
 
94
124
  def controller_params_filters_fields
@@ -10,8 +10,6 @@ module Restme
10
10
  MAX_PER_PAGE = ENV.fetch("PAGINATION_MAX_PER_PAGE", 100)
11
11
 
12
12
  def paginable_scope(user_scope)
13
- per_page_error
14
-
15
13
  user_scope.limit(per_page).offset(paginate_offset)
16
14
  end
17
15
 
@@ -35,7 +33,7 @@ module Restme
35
33
  (page_no - 1) * per_page
36
34
  end
37
35
 
38
- def per_page_error
36
+ def per_page_errors
39
37
  return if per_page <= MAX_PER_PAGE
40
38
 
41
39
  restme_scope_errors(
@@ -46,6 +44,8 @@ module Restme
46
44
  )
47
45
 
48
46
  restme_scope_status(:bad_request)
47
+
48
+ true
49
49
  end
50
50
  end
51
51
  end
@@ -23,20 +23,24 @@ module Restme
23
23
  include ::Restme::Shared::UserRole
24
24
 
25
25
  attr_reader :filtered_scope, :sorted_scope, :paginated_scope, :fieldated_scope
26
- attr_accessor :restme_scope_errors, :restme_scope_status
26
+ attr_writer :restme_scope_errors, :restme_scope_status
27
27
 
28
28
  def pagination_response
29
29
  @pagination_response ||= restme_response
30
30
  end
31
31
 
32
32
  def model_scope_object
33
- @model_scope_object ||= model_scope.first
33
+ @model_scope_object ||= begin
34
+ model_scope unless any_scope_errors.present?
35
+
36
+ restme_scope_errors.presence || model_scope.first
37
+ end
34
38
  end
35
39
 
36
40
  private
37
41
 
38
42
  def restme_response
39
- model_scope
43
+ any_scope_errors
40
44
 
41
45
  restme_scope_errors.presence || {
42
46
  objects: model_scope,
@@ -44,6 +48,15 @@ module Restme
44
48
  }
45
49
  end
46
50
 
51
+ def any_scope_errors
52
+ per_page_errors
53
+ unknown_sortable_fields_errors
54
+ unallowed_filter_fields_errors
55
+ unallowed_select_fields_errors
56
+
57
+ restme_scope_errors
58
+ end
59
+
47
60
  def model_scope
48
61
  @model_scope ||= without_item_in_scope? ? user_scope : custom_scope
49
62
  end
@@ -57,7 +70,9 @@ module Restme
57
70
  end
58
71
 
59
72
  def restme_scope_errors(error = nil)
60
- @restme_scope_errors ||= error
73
+ @restme_scope_errors ||= []
74
+ @restme_scope_errors << error if error.present?
75
+ @restme_scope_errors
61
76
  end
62
77
 
63
78
  def restme_scope_status(status = :ok)
@@ -11,7 +11,6 @@ module Restme
11
11
 
12
12
  def sortable_scope(user_scope)
13
13
  return user_scope unless sortable_scope?
14
- return user_scope if unknown_sortable_fields_errors
15
14
 
16
15
  user_scope.order(serialize_sort_params)
17
16
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Restme
4
- VERSION = "0.0.37"
4
+ VERSION = "0.0.39"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restme
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.37
4
+ version: 0.0.39
5
5
  platform: ruby
6
6
  authors:
7
7
  - everson-ever
@@ -16,6 +16,7 @@ executables: []
16
16
  extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
+ - ".env.example"
19
20
  - ".rspec"
20
21
  - ".rubocop.yml"
21
22
  - CHANGELOG.md
@@ -55,6 +56,7 @@ metadata:
55
56
  homepage_uri: https://github.com/everson-ever/restme
56
57
  source_code_uri: https://github.com/everson-ever/restme
57
58
  changelog_uri: https://github.com/everson-ever/restme/blob/main/CHANGELOG.md
59
+ rubygems_mfa_required: 'true'
58
60
  rdoc_options: []
59
61
  require_paths:
60
62
  - lib