tramway-api 1.8.6.4 → 1.8.6.9

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: 28de923a74f0d7e402961d4a15e743c3644613c6916df046015f4dfef77b0022
4
- data.tar.gz: d9e47c9f6a6272765e241082266ac45249dc91581e5348214d9d7e84d9869f29
3
+ metadata.gz: 715fdb8596a8e3e42aaf7d8bf7150e004488f53e5522d960cb4b355c4c5d77fb
4
+ data.tar.gz: 140d4c0e45a45791677f9942995be2d9f277391e0633e804aaaa8aeb63c185da
5
5
  SHA512:
6
- metadata.gz: f18ab5bec7ffc6f68239a22c03ed02ecdb8e14918a68c29faf18253d4dcda2c7491aaabc4fb89a6d8673bf3b4d2da998f19def3cb3e57a72c25acfc516356b04
7
- data.tar.gz: 21cfd0df88415a40be0add47f7387243f9d3cba349a9bd8ad40a17de26139ff317ba206cf334e590e31a79ec1c52790be5eb289984336b52540de1df4274d993
6
+ metadata.gz: b1a164a8e6aff4f1a6485ff3952a488fa74f7a3baf21d2c2cb12b5b22d56f6a79bfbd98932ec8740a8d06c8833a756b5eebf1038cef754450226be6287161139
7
+ data.tar.gz: 9aeb6d5b7699ac269dde2417a8a1c9a742cbabaff6505731fc42055d1af548539cc379600cbd73818caf68e90e1a8d05e17da5552d6085be853c1e26f5dd647f
data/README.md CHANGED
@@ -41,7 +41,6 @@ coming soon...
41
41
  ```ruby
42
42
  gem 'active_model_serializers', '0.10.5'
43
43
  gem 'tramway-core'
44
- gem 'state_machine', github: 'seuros/state_machine'
45
44
  gem 'knock'
46
45
  gem 'audited'
47
46
  gem 'ransack'
@@ -105,10 +104,18 @@ To choose your own public ID method, just add this line to:
105
104
  *config/initializers/tramway.rb*
106
105
 
107
106
  ```ruby
108
- Tramway::Api.id_methods_of(User => :id)
107
+ Tramway::Api.id_methods_of(User => { default: :id })
109
108
  ```
110
109
  If you want to use `uuid` by default, please, add it to your models
111
110
 
111
+ ### Also, you can add array of secondary methods as IDs, but you'll need to add their names to a request
112
+
113
+ ```ruby
114
+ Tramway::Api.id_methods_of(User => { default: id, other: :email }
115
+ ```
116
+
117
+ in this case your request will look like this `/api/v1/records/someEmail@mail.com?model=User&key=email`
118
+
112
119
  #### Add generating uuid by default to every model, that is accessible by API
113
120
 
114
121
  *db/migrate/add_uuid_to_some_model.rb*
@@ -138,7 +145,7 @@ end
138
145
 
139
146
  #### Configurate available models. Tramway will create end points according to this config
140
147
 
141
- ```
148
+ ```ruby
142
149
  ::Tramway::Api.set_available_models({
143
150
  User => [
144
151
  {
@@ -286,7 +293,6 @@ RSpec.describe 'Post generate token', type: :feature do
286
293
 
287
294
  end
288
295
  end
289
-
290
296
  ```
291
297
 
292
298
  Run `rspec` to test
@@ -332,11 +338,6 @@ this model must have field `password_digest`, because we use `bcrypt` gem for au
332
338
 
333
339
  Sets ActiveRecord models which will be used in API
334
340
 
335
- Argument is a hash. Keys are underscored models names, values are hashes with actions of available methods for every model.
336
- * `open` key means that this action will be used without authentication
337
- * `closed` key means that this action will be used with authentication
338
-
339
-
340
341
  Enabled methods:
341
342
 
342
343
  * create
@@ -352,7 +353,7 @@ Every model you've added in initializer will be able by URL `api/v1/records?mode
352
353
  Just update your initializer:
353
354
 
354
355
  ```ruby
355
- ::Tramway::Api.set_available_models user: { open: %i[create], closed: %i[update index] } # we've added index method
356
+ ::Tramway::Api.set_available_models({ User => { %i[index] })
356
357
  ```
357
358
 
358
359
  Create serializer
@@ -383,6 +384,8 @@ end
383
384
 
384
385
  You have your records in JSON API spec.
385
386
 
387
+ You also able to use pagination, provided by `kaminari`
388
+
386
389
  ### Create
387
390
 
388
391
  *config/initializers/tramway.rb*
@@ -426,6 +429,46 @@ Params Structure
426
429
  }
427
430
  ```
428
431
 
432
+ Also, you can test it with this
433
+
434
+ *spec/factories/your_models.rb*
435
+
436
+ ```ruby
437
+ FactoryBot.define do
438
+ factory :your_model do
439
+ attribute1 { # some code which generate value for this attribute }
440
+ attribute2 { # some code which generate value for this attribute }
441
+ name { generate :name }
442
+ end
443
+ end
444
+ ```
445
+
446
+ *spec/api/your_model_spec.rb*
447
+
448
+ ```ruby
449
+ require 'rails_helper'
450
+
451
+ RSpec.describe 'Post generate token', type: :feature do
452
+ describe 'POST /api/v1/user_token' do
453
+ let(:user) { create :user, password: '123456789' }
454
+
455
+ it 'returns created status' do
456
+ post '/api/v1/user_token', params: { auth: { login: user.email, password: '123456789' } }
457
+
458
+ expect(response.status).to eq 201
459
+ end
460
+
461
+ it 'returns token' do
462
+ post '/api/v1/user_token', params: { auth: { login: user.email, password: '123456789' } }
463
+
464
+ expect(json_response[:auth_token].present?).to be_truthy
465
+ expect(json_response[:user]).to include_json({ email: user.email, uuid: user.uuid })
466
+ end
467
+
468
+ end
469
+ end
470
+ ```
471
+
429
472
  ### Update
430
473
 
431
474
  *config/initializers/tramway.rb*
@@ -58,9 +58,7 @@ module Tramway
58
58
 
59
59
  def current_user
60
60
  Tramway::Api.user_based_models.map do |user_based_model|
61
- unless user_based_model == User
62
- send("current_#{user_based_model.name.underscore}")
63
- end
61
+ send("current_#{user_based_model.name.underscore}") unless user_based_model == User
64
62
  end.compact.first
65
63
  end
66
64
  end
@@ -4,6 +4,8 @@ module Tramway
4
4
  module Api
5
5
  module V1
6
6
  class ApplicationController < ::Tramway::Api::ApplicationController
7
+ before_action :application
8
+
7
9
  def render_errors_for(model)
8
10
  render json: model, status: :unprocessable_entity, serializer: ::Tramway::Api::V1::ErrorSerializer
9
11
  end
@@ -45,6 +47,7 @@ module Tramway
45
47
  def check_available_model_class
46
48
  unless model_class
47
49
  head(:unauthorized) && return unless current_user
50
+
48
51
  head(:unprocessable_entity) && return
49
52
  end
50
53
  end
@@ -69,7 +72,7 @@ module Tramway
69
72
  action_is_available = checking_roles.map do |role|
70
73
  Tramway::Api.action_is_available(
71
74
  action: action_name.to_sym,
72
- project: (@application_engine || @application.name),
75
+ project: (@application_engine || application_name),
73
76
  role: role,
74
77
  model_name: params[:model],
75
78
  current_user: current_user
@@ -90,7 +93,7 @@ module Tramway
90
93
  def authenticate_user_if_needed
91
94
  action_is_open = Tramway::Api.action_is_available(
92
95
  action: action_name.to_sym,
93
- project: (@application_engine || @application.name),
96
+ project: (@application_engine || application_name),
94
97
  model_name: params[:model]
95
98
  )
96
99
  head(:unauthorized) && return if !current_user && !action_is_open
@@ -108,14 +111,27 @@ module Tramway
108
111
 
109
112
  protected
110
113
 
111
- def model_class
112
- begin
113
- params[:model].constantize
114
- rescue ActiveSupport::Concern::MultipleIncludedBlocks => e
115
- raise "#{e}. Maybe #{params[:model]} model doesn't exists or there is naming conflicts with it"
114
+ def application_name
115
+ if @application.present?
116
+ @application.name
117
+ else
118
+ if ::Tramway::Core.application
119
+ @application = Tramway::Core.application&.model_class&.first || Tramway::Core.application
120
+ end
121
+ if @application.present?
122
+ @application.name
123
+ else
124
+ raise("Tramway::Api @application not initialized, Tramway::Core.application: #{::Tramway::Core.application}, model_class: #{Tramway::Core.application&.model_class }")
125
+ end
116
126
  end
117
127
  end
118
128
 
129
+ def model_class
130
+ params[:model].constantize
131
+ rescue ActiveSupport::Concern::MultipleIncludedBlocks => e
132
+ raise "#{e}. Maybe #{params[:model]} model doesn't exists or there is naming conflicts with it"
133
+ end
134
+
119
135
  def decorator_class(model_name = nil)
120
136
  "#{model_name || model_class}Decorator".constantize
121
137
  end
@@ -5,6 +5,7 @@ module Tramway::Api::V1
5
5
  before_action :check_available_model_class
6
6
  before_action :check_available_model_action_for_record, only: %i[show update destroy]
7
7
  before_action :authenticate_user_if_needed
8
+ before_action :application
8
9
 
9
10
  def index
10
11
  collection = available_action_for_collection
@@ -54,5 +55,11 @@ module Tramway::Api::V1
54
55
  include: '*',
55
56
  status: :no_content
56
57
  end
58
+
59
+ def application
60
+ if ::Tramway::Core.application
61
+ @application = Tramway::Core.application&.model_class&.first || Tramway::Core.application
62
+ end
63
+ end
57
64
  end
58
65
  end
@@ -16,25 +16,29 @@ class Tramway::Api::V1::ErrorSerializer < ActiveModel::Serializer
16
16
  def error_messages(object, path = []) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
17
17
  error_messages = {}
18
18
 
19
- object.errors.messages.each do |name, messages|
20
- error_messages.merge!((path + [name]).join('/') => messages)
21
- end
22
-
23
- if object.model
24
- object.model.errors.messages.each do |name, messages|
19
+ if object.respond_to? :errors
20
+ object.errors.messages.each do |name, messages|
25
21
  error_messages.merge!((path + [name]).join('/') => messages)
26
22
  end
27
23
  end
28
24
 
29
- object.model&.attributes&.each do |attribute_key, attribute_value|
30
- if attribute_value.is_a?(Array)
31
- attribute_value.each_with_index do |array_attribute_value, array_attribute_key|
32
- error_messages.merge!(
33
- error_messages(
34
- array_attribute_value,
35
- path + [attribute_key] + [array_attribute_key]
25
+ if object.respond_to? :model
26
+ if object.model
27
+ object.model.errors.messages.each do |name, messages|
28
+ error_messages.merge!((path + [name]).join('/') => messages)
29
+ end
30
+ end
31
+
32
+ object.model&.attributes&.each do |attribute_key, attribute_value|
33
+ if attribute_value.is_a?(Array)
34
+ attribute_value.each_with_index do |array_attribute_value, array_attribute_key|
35
+ error_messages.merge!(
36
+ error_messages(
37
+ array_attribute_value,
38
+ path + [attribute_key] + [array_attribute_key]
39
+ )
36
40
  )
37
- )
41
+ end
38
42
  end
39
43
  end
40
44
  end
data/lib/tramway/api.rb CHANGED
@@ -96,7 +96,8 @@ module Tramway
96
96
  end
97
97
 
98
98
  def default_id_method_of(model:)
99
- @@id_methods[model.to_s][:default]
99
+ @@id_methods ||= {}
100
+ @@id_methods.dig(model.to_s, :default)
100
101
  end
101
102
  end
102
103
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Tramway
4
4
  module Api
5
- VERSION = '1.8.6.4'
5
+ VERSION = '1.8.6.9'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tramway-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.6.4
4
+ version: 1.8.6.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel Kalashnikov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-26 00:00:00.000000000 Z
11
+ date: 2021-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_model_serializers
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.9.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: uuid
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  description: Engine for api
56
70
  email:
57
71
  - kalashnikovisme@gmail.com
@@ -102,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
116
  - !ruby/object:Gem::Version
103
117
  version: '0'
104
118
  requirements: []
105
- rubygems_version: 3.1.2
119
+ rubygems_version: 3.1.4
106
120
  signing_key:
107
121
  specification_version: 4
108
122
  summary: Engine for api