standardapi 6.0.0.15 → 6.0.0.29
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -6
- data/lib/standard_api.rb +2 -0
- data/lib/standard_api/active_record/connection_adapters/postgresql/schema_statements.rb +21 -0
- data/lib/standard_api/controller.rb +77 -66
- data/lib/standard_api/errors.rb +13 -0
- data/lib/standard_api/helpers.rb +67 -15
- data/lib/standard_api/includes.rb +22 -12
- data/lib/standard_api/orders.rb +4 -6
- data/lib/standard_api/railtie.rb +1 -1
- data/lib/standard_api/route_helpers.rb +4 -0
- data/lib/standard_api/test_case/calculate_tests.rb +5 -3
- data/lib/standard_api/test_case/create_tests.rb +0 -3
- data/lib/standard_api/test_case/schema_tests.rb +19 -3
- data/lib/standard_api/version.rb +1 -1
- data/lib/standard_api/views/application/_record.json.jbuilder +11 -10
- data/lib/standard_api/views/application/_record.streamer +11 -10
- data/lib/standard_api/views/application/_schema.json.jbuilder +68 -0
- data/lib/standard_api/views/application/_schema.streamer +78 -0
- data/lib/standard_api/views/application/index.json.jbuilder +9 -16
- data/lib/standard_api/views/application/index.streamer +9 -16
- data/lib/standard_api/views/application/schema.json.jbuilder +1 -12
- data/lib/standard_api/views/application/schema.streamer +1 -16
- data/lib/standard_api/views/application/show.json.jbuilder +8 -1
- data/lib/standard_api/views/application/show.streamer +8 -1
- data/test/standard_api/test_app.rb +55 -0
- data/test/standard_api/test_app/config/database.yml +4 -0
- data/test/standard_api/test_app/controllers.rb +107 -0
- data/test/standard_api/test_app/models.rb +94 -0
- data/test/standard_api/test_app/test/factories.rb +50 -0
- data/test/standard_api/test_app/test/fixtures/photo.png +0 -0
- data/test/standard_api/test_app/views/photos/_photo.json.jbuilder +15 -0
- data/test/standard_api/test_app/views/photos/_photo.streamer +17 -0
- data/test/standard_api/test_app/views/photos/_schema.json.jbuilder +1 -0
- data/test/standard_api/test_app/views/photos/_schema.streamer +3 -0
- data/test/standard_api/test_app/views/photos/schema.json.jbuilder +1 -0
- data/test/standard_api/test_app/views/photos/schema.streamer +1 -0
- data/test/standard_api/test_app/views/properties/edit.html.erb +1 -0
- data/test/standard_api/test_app/views/sessions/new.html.erb +0 -0
- metadata +27 -8
@@ -1,20 +1,17 @@
|
|
1
|
-
if !
|
2
|
-
|
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
|
-
|
7
|
-
|
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
|
-
|
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!
|
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.
|
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.
|
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
|
-
|
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
|
-
|
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,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
|
Binary file
|
@@ -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
|