standardapi 6.0.0.15 → 6.0.0.29

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -6
  3. data/lib/standard_api.rb +2 -0
  4. data/lib/standard_api/active_record/connection_adapters/postgresql/schema_statements.rb +21 -0
  5. data/lib/standard_api/controller.rb +77 -66
  6. data/lib/standard_api/errors.rb +13 -0
  7. data/lib/standard_api/helpers.rb +67 -15
  8. data/lib/standard_api/includes.rb +22 -12
  9. data/lib/standard_api/orders.rb +4 -6
  10. data/lib/standard_api/railtie.rb +1 -1
  11. data/lib/standard_api/route_helpers.rb +4 -0
  12. data/lib/standard_api/test_case/calculate_tests.rb +5 -3
  13. data/lib/standard_api/test_case/create_tests.rb +0 -3
  14. data/lib/standard_api/test_case/schema_tests.rb +19 -3
  15. data/lib/standard_api/version.rb +1 -1
  16. data/lib/standard_api/views/application/_record.json.jbuilder +11 -10
  17. data/lib/standard_api/views/application/_record.streamer +11 -10
  18. data/lib/standard_api/views/application/_schema.json.jbuilder +68 -0
  19. data/lib/standard_api/views/application/_schema.streamer +78 -0
  20. data/lib/standard_api/views/application/index.json.jbuilder +9 -16
  21. data/lib/standard_api/views/application/index.streamer +9 -16
  22. data/lib/standard_api/views/application/schema.json.jbuilder +1 -12
  23. data/lib/standard_api/views/application/schema.streamer +1 -16
  24. data/lib/standard_api/views/application/show.json.jbuilder +8 -1
  25. data/lib/standard_api/views/application/show.streamer +8 -1
  26. data/test/standard_api/test_app.rb +55 -0
  27. data/test/standard_api/test_app/config/database.yml +4 -0
  28. data/test/standard_api/test_app/controllers.rb +107 -0
  29. data/test/standard_api/test_app/models.rb +94 -0
  30. data/test/standard_api/test_app/test/factories.rb +50 -0
  31. data/test/standard_api/test_app/test/fixtures/photo.png +0 -0
  32. data/test/standard_api/test_app/views/photos/_photo.json.jbuilder +15 -0
  33. data/test/standard_api/test_app/views/photos/_photo.streamer +17 -0
  34. data/test/standard_api/test_app/views/photos/_schema.json.jbuilder +1 -0
  35. data/test/standard_api/test_app/views/photos/_schema.streamer +3 -0
  36. data/test/standard_api/test_app/views/photos/schema.json.jbuilder +1 -0
  37. data/test/standard_api/test_app/views/photos/schema.streamer +1 -0
  38. data/test/standard_api/test_app/views/properties/edit.html.erb +1 -0
  39. data/test/standard_api/test_app/views/sessions/new.html.erb +0 -0
  40. metadata +27 -8
@@ -1,20 +1,17 @@
1
- if !includes.empty?
2
- instance_variable_set("@#{model.model_name.plural}", preloadables(instance_variable_get("@#{model.model_name.plural}"), includes))
1
+ if !defined?(records)
2
+ records = instance_variable_get("@#{model.model_name.plural}")
3
3
  end
4
4
 
5
+ partial = model_partial(model)
6
+ partial_record_name = partial.split('/').last.to_sym
7
+
5
8
  if !includes.empty? && can_cache?(model, includes)
6
- partial = model_partial(model)
7
- record_name = partial.split('/').last.to_sym
8
-
9
- json.cache_collection! instance_variable_get("@#{model.model_name.plural}"), key: proc {|record| cache_key(record, includes) } do |record|
10
- locals = { record: record, record_name => record, :includes => includes }
11
- json.partial! partial, locals
9
+ json.cache_collection! records, key: proc { |record| cache_key(record, includes) } do |record|
10
+ json.partial!(partial, includes: includes, partial_record_name => record)
12
11
  end
13
12
  else
14
- partial = model_partial(model)
15
- record_name = partial.split('/').last.to_sym
16
13
  json.array! do
17
- instance_variable_get("@#{model.model_name.plural}").each do |record|
14
+ records.each do |record|
18
15
  sub_includes = includes.select do |key, value|
19
16
  case value
20
17
  when Hash, ActionController::Parameters
@@ -28,11 +25,7 @@ else
28
25
  end
29
26
  end
30
27
 
31
- json.partial! partial, {
32
- record: record,
33
- record_name => record,
34
- includes: sub_includes
35
- }
28
+ json.partial!(partial, includes: sub_includes, partial_record_name => record)
36
29
  end
37
30
  end
38
31
  end
@@ -1,12 +1 @@
1
- json.set! 'columns' do
2
- model.columns.each do |column|
3
- json.set! column.name, {
4
- type: json_column_type(column.sql_type),
5
- primary_key: column.name == model.primary_key,
6
- null: column.null,
7
- array: column.array
8
- }
9
- end
10
- end
11
-
12
- json.set! 'limit', resource_limit
1
+ json.partial!('schema', model: model)
@@ -1,16 +1 @@
1
- json.object! do
2
- json.set! 'columns' do
3
- json.object! do
4
- model.columns.each do |column|
5
- json.set! column.name, {
6
- type: json_column_type(column.sql_type),
7
- primary_key: column.name == model.primary_key,
8
- null: column.null,
9
- array: column.array
10
- }
11
- end
12
- end
13
- end
14
-
15
- json.set! 'limit', resource_limit
16
- end
1
+ json.partial!('schema', model: model)
@@ -1 +1,8 @@
1
- json.partial! model_partial(model), model_partial(model).split('/').last.to_sym => instance_variable_get("@#{model.model_name.singular}"), includes: includes
1
+ if !defined?(record)
2
+ record = instance_variable_get("@#{model.model_name.singular}")
3
+ end
4
+
5
+ partial = model_partial(model)
6
+ partial_record_name = partial.split('/').last.to_sym
7
+
8
+ json.partial!(partial, partial_record_name => record, includes: includes)
@@ -1 +1,8 @@
1
- json.partial! model_partial(model), model_partial(model).split('/').last.to_sym => instance_variable_get("@#{model.model_name.singular}"), includes: includes
1
+ if !defined?(record)
2
+ record = instance_variable_get("@#{model.model_name.singular}")
3
+ end
4
+
5
+ partial = model_partial(model)
6
+ partial_record_name = partial.split('/').last.to_sym
7
+
8
+ json.partial!(partial, partial_record_name => record, includes: includes)
@@ -0,0 +1,55 @@
1
+ require "rails"
2
+ require "active_model/railtie"
3
+ require "active_record/railtie"
4
+ require "action_controller/railtie"
5
+ require "action_view/railtie"
6
+ require "rails/test_unit/railtie"
7
+ Bundler.require(*Rails.groups)
8
+
9
+ require 'standard_api'
10
+
11
+ # Test Application Config
12
+ Rails.env = 'test'
13
+
14
+ class TestApplication < Rails::Application
15
+ config.root = File.join(File.dirname(__FILE__), 'test_app')
16
+ config.secret_key_base = 'test key base'
17
+ config.eager_load = true
18
+ config.cache_classes = true
19
+ config.action_controller.perform_caching = true
20
+ config.cache_store = :memory_store, { size: 8.megabytes }
21
+ config.action_dispatch.show_exceptions = false
22
+
23
+ # if defined?(FactoryBotRails)
24
+ # config.factory_bot.definition_file_paths += [ '../factories' ]
25
+ # end
26
+ end
27
+
28
+ # Test Application initialization
29
+ TestApplication.initialize!
30
+
31
+ # Test Application Models
32
+ require 'standard_api/test_app/models'
33
+
34
+ # Test Application Controllers
35
+ require 'standard_api/test_app/controllers'
36
+
37
+ # Test Application Routes
38
+ Rails.application.routes.draw do
39
+ get :tables, to: 'application#tables', as: :tables
40
+ get :schema, to: 'application#schema', as: :schema
41
+
42
+ [:properties, :photos, :documents, :references, :sessions, :unlimited, :default_limit].each do |r|
43
+ standard_resources r
44
+ end
45
+
46
+ standard_resource :account
47
+ end
48
+
49
+ # Test Application Helpers
50
+ Object.const_set(:ApplicationHelper, Module.new)
51
+
52
+ # require 'turbostreamer'
53
+ # require 'wankel'
54
+ # ActionView::Template.unregister_template_handler :jbuilder
55
+ # ActionView::Template.register_template_handler :streamer, TurboStreamer::Handler
@@ -0,0 +1,4 @@
1
+ test:
2
+ adapter: postgresql
3
+ database: standardapi-test
4
+ encoding: utf8
@@ -0,0 +1,107 @@
1
+ class ApplicationController < ActionController::Base
2
+ include StandardAPI::Controller
3
+ prepend_view_path File.join(File.dirname(__FILE__), 'views')
4
+
5
+ private
6
+
7
+ def account_params
8
+ [ "property_id", "name" ]
9
+ end
10
+
11
+ def account_orders
12
+ [ "id" ]
13
+ end
14
+
15
+ def account_includes
16
+ [ "photos" ]
17
+ end
18
+
19
+ def property_params
20
+ [ :name,
21
+ :aliases,
22
+ :description,
23
+ :constructed,
24
+ :size,
25
+ :active,
26
+ :photos_attributes,
27
+ { photos_attributes: [ :id, :account_id, :property_id, :format] }
28
+ ]
29
+ end
30
+
31
+ def property_orders
32
+ ["id", "name", "aliases", "description", "constructed", "size", "created_at", "active"]
33
+ end
34
+
35
+ def property_includes
36
+ [:photos, :landlord, :english_name]
37
+ end
38
+
39
+ def reference_includes
40
+ { subject: [ :landlord, :photos ] }
41
+ end
42
+
43
+ end
44
+
45
+ class PropertiesController < ApplicationController
46
+ end
47
+
48
+ class AccountsController < ApplicationController
49
+ end
50
+
51
+ class DocumentsController < ApplicationController
52
+
53
+ def document_params
54
+ [ :file, :type ]
55
+ end
56
+
57
+ def document_orders
58
+ [:id]
59
+ end
60
+
61
+ end
62
+
63
+ class PhotosController < ApplicationController
64
+
65
+ def photo_params
66
+ [ :id, :account_id, :property_id, :format ]
67
+ end
68
+
69
+ def photo_orders
70
+ [:id]
71
+ end
72
+
73
+ def photo_includes
74
+ [:account]
75
+ end
76
+
77
+ end
78
+
79
+ class ReferencesController < ApplicationController
80
+ end
81
+
82
+ class SessionsController < ApplicationController
83
+ end
84
+
85
+ class UnlimitedController < ApplicationController
86
+
87
+ def self.model
88
+ Account
89
+ end
90
+
91
+ def resource_limit
92
+ nil
93
+ end
94
+
95
+ end
96
+
97
+ class DefaultLimitController < ApplicationController
98
+
99
+ def self.model
100
+ Account
101
+ end
102
+
103
+ def default_limit
104
+ 100
105
+ end
106
+
107
+ end
@@ -0,0 +1,94 @@
1
+ # = Models
2
+
3
+ class Account < ActiveRecord::Base
4
+ has_many :photos
5
+ belongs_to :property
6
+ end
7
+
8
+ class Photo < ActiveRecord::Base
9
+ belongs_to :account, :counter_cache => true
10
+ has_and_belongs_to_many :properties
11
+ end
12
+
13
+ class Document < ActiveRecord::Base
14
+ attr_accessor :file
15
+ end
16
+
17
+ class Pdf < Document
18
+ end
19
+
20
+ class Property < ActiveRecord::Base
21
+ has_and_belongs_to_many :photos
22
+ has_many :accounts
23
+ has_one :landlord, class_name: 'Account'
24
+
25
+ validates :name, presence: true
26
+ accepts_nested_attributes_for :photos
27
+
28
+ def english_name
29
+ 'A Name'
30
+ end
31
+ end
32
+
33
+ class Reference < ActiveRecord::Base
34
+ belongs_to :subject, polymorphic: true
35
+ end
36
+
37
+ # = Migration
38
+
39
+ class CreateModelTables < ActiveRecord::Migration[6.0]
40
+
41
+ def self.up
42
+
43
+ comment = "test comment"
44
+ exec_query(<<-SQL, "SQL")
45
+ COMMENT ON DATABASE #{quote_column_name(current_database)} IS #{quote(comment)};
46
+ SQL
47
+
48
+ create_table "accounts", force: :cascade do |t|
49
+ t.string 'name', limit: 255
50
+ t.integer 'property_id'
51
+ t.integer 'photos_count', null: false, default: 0
52
+ end
53
+
54
+ create_table "photos", force: :cascade do |t|
55
+ t.integer "account_id"
56
+ t.integer "property_id"
57
+ t.string "format", limit: 255
58
+ end
59
+
60
+ create_table "properties", force: :cascade do |t|
61
+ t.string "name", limit: 255
62
+ t.string "aliases", default: [], array: true
63
+ t.text "description"
64
+ t.integer "constructed"
65
+ t.decimal "size"
66
+ t.datetime "created_at", null: false
67
+ t.boolean "active", default: false
68
+ end
69
+
70
+ create_table "references", force: :cascade do |t|
71
+ t.integer "subject_id"
72
+ t.string "subject_type", limit: 255
73
+ t.string "key"
74
+ t.string "value"
75
+ end
76
+
77
+ create_table "photos_properties", force: :cascade do |t|
78
+ t.integer "photo_id"
79
+ t.integer "property_id"
80
+ end
81
+
82
+ create_table "landlords_properties", force: :cascade do |t|
83
+ t.integer "landlord_id"
84
+ t.integer "property_id"
85
+ end
86
+
87
+ create_table "documents", force: :cascade do |t|
88
+ t.string 'type'
89
+ end
90
+ end
91
+
92
+ end
93
+ ActiveRecord::Migration.verbose = false
94
+ CreateModelTables.up
@@ -0,0 +1,50 @@
1
+ FactoryBot.define do
2
+ factory :account do
3
+ name { Faker::Name.name }
4
+
5
+ trait(:nested) { }
6
+ trait(:invalid) do
7
+ name { nil }
8
+ end
9
+ end
10
+
11
+ factory :landlord do
12
+ name { Faker::Name.name }
13
+ end
14
+
15
+ factory :photo do
16
+ format { ['jpg', 'png', 'tiff'].sample }
17
+ end
18
+
19
+ factory :document do
20
+ file { fixture_file_upload(Rails.root + 'test/fixtures/photo.png', 'image/png') }
21
+ end
22
+
23
+ factory :pdf do
24
+ type { 'Pdf' }
25
+ file { fixture_file_upload(Rails.root + 'test/fixtures/photo.png', 'image/png') }
26
+ end
27
+
28
+ factory :reference do
29
+ subject_type { 'Photo' }
30
+ subject_id { create(:photo).id }
31
+ end
32
+
33
+ factory :property do
34
+ name { Faker::Lorem.words(number: Kernel.rand(1..4)).join(' ') }
35
+ description { Faker::Lorem.paragraphs.join("\n\n") }
36
+ constructed { Kernel.rand(1800..(Time.now.year - 2)) }
37
+ size { Kernel.rand(1000..10000000).to_f / 100 }
38
+ active { [true, false].sample }
39
+ photos { [create(:photo)] }
40
+
41
+ trait(:nested) do
42
+ photos_attributes { [attributes_for(:photo)] }
43
+ end
44
+
45
+ trait(:invalid) do
46
+ name { nil }
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,15 @@
1
+ json.set! :id, photo.id
2
+ json.set! :account_id, photo.account_id
3
+ json.set! :property_id, photo.property_id
4
+ json.set! :format, photo.format
5
+ json.set! :template, 'photos/_photo'
6
+
7
+ if includes[:account]
8
+ json.set! :account do
9
+ if photo.account
10
+ json.partial! 'application/record', record: photo.account, includes: includes[:account]
11
+ else
12
+ json.null!
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ json.object! do
2
+ json.set! :id, photo.id
3
+ json.set! :account_id, photo.account_id
4
+ json.set! :property_id, photo.property_id
5
+ json.set! :format, photo.format
6
+ json.set! :template, 'photos/_photo'
7
+
8
+ if includes[:account]
9
+ json.set! :account do
10
+ if photo.account
11
+ json.partial! 'application/record', record: photo.account, includes: includes[:account]
12
+ else
13
+ json.null!
14
+ end
15
+ end
16
+ end
17
+ end