Skip to content

Commit 7e9fd44

Browse files
authored
Support Rails 6.1
* Setup github actions for CI (cherry picked from commit e894827) * Rails 6.1 (#1352) * Rails v6.1 compatibility (#1346) * Fixes for rails 6.1.1 * Fixes for ruby 3.0.0 * Remove rails 5.0 support Co-authored-by: Igor Gonchar <gigorok@gmail.com> (cherry picked from commit 1322b59)
1 parent ba1c1b6 commit 7e9fd44

File tree

10 files changed

+107
-55
lines changed

10 files changed

+107
-55
lines changed

.github/workflows/ruby.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ 'master', 'release-0-8', 'release-0-9', 'release-0-10' ]
6+
pull_request:
7+
branches: ['**']
8+
9+
jobs:
10+
tests:
11+
runs-on: ubuntu-latest
12+
services:
13+
postgres:
14+
image: postgres
15+
env:
16+
POSTGRES_PASSWORD: password
17+
POSTGRES_DB: test
18+
options: >-
19+
--health-cmd pg_isready
20+
--health-interval 10s
21+
--health-timeout 5s
22+
--health-retries 5
23+
ports:
24+
- 5432:5432
25+
strategy:
26+
fail-fast: false
27+
matrix:
28+
ruby:
29+
- 2.6.6
30+
- 2.7.2
31+
- 3.0.0
32+
rails:
33+
- 6.1.1
34+
- 6.0.3.4
35+
- 5.2.4.4
36+
- 5.1.7
37+
database_url:
38+
- postgresql://postgres:password@localhost:5432/test
39+
- sqlite3:test_db
40+
exclude:
41+
- ruby: 3.0.0
42+
rails: 6.0.3.4
43+
- ruby: 3.0.0
44+
rails: 5.2.4.4
45+
- ruby: 3.0.0
46+
rails: 5.1.7
47+
- database_url: postgresql://postgres:password@localhost:5432/test
48+
rails: 5.1.7
49+
env:
50+
RAILS_VERSION: ${{ matrix.rails }}
51+
DATABASE_URL: ${{ matrix.database_url }}
52+
name: Ruby ${{ matrix.ruby }} Rails ${{ matrix.rails }} DB ${{ matrix.database_url }}
53+
steps:
54+
- uses: actions/checkout@v2
55+
- name: Set up Ruby
56+
uses: ruby/setup-ruby@v1
57+
with:
58+
ruby-version: ${{ matrix.ruby }}
59+
- name: Install dependencies
60+
run: bundle install --jobs 4 --retry 3
61+
- name: Run tests
62+
run: bundle exec rake test

.travis.yml

Lines changed: 0 additions & 31 deletions
This file was deleted.

lib/jsonapi/active_relation_resource.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,7 @@ def apply_single_sort(records, field, direction, options)
756756

757757
# Assumes ActiveRecord's counting. Override if you need a different counting method
758758
def count_records(records)
759-
if Rails::VERSION::MAJOR >= 5 && ActiveRecord::VERSION::MINOR >= 1
759+
if (Rails::VERSION::MAJOR == 5 && ActiveRecord::VERSION::MINOR >= 1) || Rails::VERSION::MAJOR >= 6
760760
records.count(:all)
761761
else
762762
records.count

lib/jsonapi/request_parser.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ def parse_sort_criteria(resource_klass, sort_criteria)
418418
sorts = sort_criteria
419419
elsif sort_criteria.is_a?(String)
420420
begin
421-
raw = URI.unescape(sort_criteria)
421+
raw = URI.decode_www_form_component(sort_criteria)
422422
sorts = CSV.parse_line(raw)
423423
rescue CSV::MalformedCSVError
424424
fail JSONAPI::Exceptions::InvalidSortCriteria.new(format_key(resource_klass._type), raw)

lib/jsonapi/resource_controller_metal.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ class ResourceControllerMetal < ActionController::Metal
55
ActionController::Rendering,
66
ActionController::Renderers::All,
77
ActionController::StrongParameters,
8-
ActionController::ForceSSL,
8+
Gem::Requirement.new('< 6.1').satisfied_by?(ActionPack.gem_version) ? ActionController::ForceSSL : nil,
99
ActionController::Instrumentation,
1010
JSONAPI::ActsAsResourceController
11-
].freeze
11+
].compact.freeze
1212

1313
# Note, the url_helpers are not loaded. This will prevent links from being generated for resources, and warnings
1414
# will be emitted. Link support can be added by including `Rails.application.routes.url_helpers`, and links

test/fixtures/active_record.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ class Post < ActiveRecord::Base
503503
belongs_to :writer, class_name: 'Person', foreign_key: 'author_id'
504504
has_many :comments
505505
has_and_belongs_to_many :tags, join_table: :posts_tags
506-
has_many :special_post_tags, source: :tag
506+
has_many :special_post_tags
507507
has_many :special_tags, through: :special_post_tags, source: :tag
508508
belongs_to :section
509509
belongs_to :parent_post, class_name: 'Post', foreign_key: 'parent_post_id'
@@ -745,8 +745,8 @@ class Picture < ActiveRecord::Base
745745
belongs_to :author, class_name: 'Person', foreign_key: 'author_id'
746746

747747
belongs_to :imageable, polymorphic: true
748-
belongs_to :document, -> { where( pictures: { imageable_type: 'Document' } ).eager_load( :pictures ) }, foreign_key: 'imageable_id'
749-
belongs_to :product, -> { where( pictures: { imageable_type: 'Product' } ).eager_load( :pictures ) }, foreign_key: 'imageable_id'
748+
belongs_to :document, -> { where( pictures: { imageable_type: 'Document' } ) }, foreign_key: 'imageable_id'
749+
belongs_to :product, -> { where( pictures: { imageable_type: 'Product' } ) }, foreign_key: 'imageable_id'
750750

751751
has_one :file_properties, as: 'fileable'
752752
end

test/integration/requests/request_test.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,7 +1608,7 @@ def test_caching_included_singleton
16081608
}
16091609

16101610
$test_user = Person.find(1001)
1611-
assert_equal 2, JSONAPI.configuration.resource_cache.instance_variable_get(:@key_access).length
1611+
assert_equal 2, JSONAPI.configuration.resource_cache.instance_variable_get(:@data).length
16121612

16131613
get "/api/v9/people/#{$test_user.id}?include=preferences"
16141614
assert_jsonapi_response 200
@@ -1655,7 +1655,7 @@ def test_caching_included_singleton
16551655
]
16561656
}
16571657

1658-
assert_equal 4, JSONAPI.configuration.resource_cache.instance_variable_get(:@key_access).length
1658+
assert_equal 4, JSONAPI.configuration.resource_cache.instance_variable_get(:@data).length
16591659

16601660
ensure
16611661
JSONAPI.configuration = original_config
@@ -1700,7 +1700,7 @@ def test_caching_singleton_primary
17001700
}
17011701
}
17021702

1703-
assert_equal 1, JSONAPI.configuration.resource_cache.instance_variable_get(:@key_access).length
1703+
assert_equal 1, JSONAPI.configuration.resource_cache.instance_variable_get(:@data).length
17041704

17051705
$test_user = Person.find(1001)
17061706

@@ -1728,7 +1728,7 @@ def test_caching_singleton_primary
17281728
}
17291729
}
17301730

1731-
assert_equal 2, JSONAPI.configuration.resource_cache.instance_variable_get(:@key_access).length
1731+
assert_equal 2, JSONAPI.configuration.resource_cache.instance_variable_get(:@data).length
17321732

17331733
ensure
17341734
JSONAPI.configuration = original_config

test/test_helper.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ class Engine < ::Rails::Engine
8888
# Monkeypatch ActionController::TestCase to delete the RAW_POST_DATA on subsequent calls in the same test.
8989
if Rails::VERSION::MAJOR >= 5
9090
module ClearRawPostHeader
91-
def process(action, *args)
91+
def process(action, **args)
9292
@request.delete_header 'RAW_POST_DATA'
93-
super
93+
super action, **args
9494
end
9595
end
9696

@@ -560,13 +560,13 @@ def assert_cacheable_jsonapi_get(url, cached_classes = :all)
560560
end
561561

562562
class ActionController::TestCase
563-
def assert_cacheable_get(action, *args)
563+
def assert_cacheable_get(action, **args)
564564
assert_nil JSONAPI.configuration.resource_cache
565565

566566
normal_queries = []
567567
normal_query_callback = lambda {|_, _, _, _, payload| normal_queries.push payload[:sql] }
568568
ActiveSupport::Notifications.subscribed(normal_query_callback, 'sql.active_record') do
569-
get action, *args
569+
get action, **args
570570
end
571571
non_caching_response = json_response_sans_all_backtraces
572572
non_caching_status = response.status
@@ -602,7 +602,7 @@ def assert_cacheable_get(action, *args)
602602
@controller = nil
603603
setup_controller_request_and_response
604604
@request.headers.merge!(orig_request_headers.dup)
605-
get action, *args
605+
get action, **args
606606
end
607607
end
608608
rescue Exception

test/unit/active_relation_resource_finder/join_manager_test.rb

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,11 @@ def test_add_nested_scoped_joins
110110
records = Api::V10::PostResource.records({})
111111
records = join_manager.join(records, {})
112112

113-
sql = 'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" LEFT OUTER JOIN "people" ON "people"."id" = "posts"."author_id" LEFT OUTER JOIN "people" "authors_comments" ON "authors_comments"."id" = "comments"."author_id" LEFT OUTER JOIN "comments_tags" ON "comments_tags"."comment_id" = "comments"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "comments_tags"."tag_id" WHERE "comments"."approved" = ' + db_true + ' AND "author"."special" = ' + db_true
113+
if (Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR >= 1) || Rails::VERSION::MAJOR > 6
114+
sql = 'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" LEFT OUTER JOIN "people" author ON author."id" = "posts"."author_id" LEFT OUTER JOIN "people" "authors_comments" ON "authors_comments"."id" = "comments"."author_id" LEFT OUTER JOIN "comments_tags" ON "comments_tags"."comment_id" = "comments"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "comments_tags"."tag_id" WHERE "comments"."approved" = ' + db_true + ' AND "author"."special" = ' + db_true
115+
else
116+
sql = 'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" LEFT OUTER JOIN "people" ON "people"."id" = "posts"."author_id" LEFT OUTER JOIN "people" "authors_comments" ON "authors_comments"."id" = "comments"."author_id" LEFT OUTER JOIN "comments_tags" ON "comments_tags"."comment_id" = "comments"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "comments_tags"."tag_id" WHERE "comments"."approved" = ' + db_true + ' AND "author"."special" = ' + db_true
117+
end
114118

115119
assert_equal sql, records.to_sql
116120

@@ -132,7 +136,11 @@ def test_add_nested_scoped_joins
132136
records = join_manager.join(records, {})
133137

134138
# Note sql is in different order, but aliases should still be right
135-
sql = 'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "people" ON "people"."id" = "posts"."author_id" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" LEFT OUTER JOIN "people" "authors_comments" ON "authors_comments"."id" = "comments"."author_id" LEFT OUTER JOIN "comments_tags" ON "comments_tags"."comment_id" = "comments"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "comments_tags"."tag_id" WHERE "comments"."approved" = ' + db_true + ' AND "author"."special" = ' + db_true
139+
if (Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR >= 1) || Rails::VERSION::MAJOR > 6
140+
sql = 'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "people" author ON author."id" = "posts"."author_id" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" LEFT OUTER JOIN "people" "authors_comments" ON "authors_comments"."id" = "comments"."author_id" LEFT OUTER JOIN "comments_tags" ON "comments_tags"."comment_id" = "comments"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "comments_tags"."tag_id" WHERE "comments"."approved" = ' + db_true + ' AND "author"."special" = ' + db_true
141+
else
142+
sql = 'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "people" ON "people"."id" = "posts"."author_id" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" LEFT OUTER JOIN "people" "authors_comments" ON "authors_comments"."id" = "comments"."author_id" LEFT OUTER JOIN "comments_tags" ON "comments_tags"."comment_id" = "comments"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "comments_tags"."tag_id" WHERE "comments"."approved" = ' + db_true + ' AND "author"."special" = ' + db_true
143+
end
136144

137145
assert_equal sql, records.to_sql
138146

@@ -171,7 +179,11 @@ def test_add_nested_joins_with_fields
171179
records = Api::V10::PostResource.records({})
172180
records = join_manager.join(records, {})
173181

174-
sql = 'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" LEFT OUTER JOIN "people" ON "people"."id" = "posts"."author_id" LEFT OUTER JOIN "people" "authors_comments" ON "authors_comments"."id" = "comments"."author_id" LEFT OUTER JOIN "comments_tags" ON "comments_tags"."comment_id" = "comments"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "comments_tags"."tag_id" WHERE "comments"."approved" = ' + db_true + ' AND "author"."special" = ' + db_true
182+
if (Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR >= 1) || Rails::VERSION::MAJOR > 6
183+
sql = 'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" LEFT OUTER JOIN "people" author ON author."id" = "posts"."author_id" LEFT OUTER JOIN "people" "authors_comments" ON "authors_comments"."id" = "comments"."author_id" LEFT OUTER JOIN "comments_tags" ON "comments_tags"."comment_id" = "comments"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "comments_tags"."tag_id" WHERE "comments"."approved" = ' + db_true + ' AND "author"."special" = ' + db_true
184+
else
185+
sql = 'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" LEFT OUTER JOIN "people" ON "people"."id" = "posts"."author_id" LEFT OUTER JOIN "people" "authors_comments" ON "authors_comments"."id" = "comments"."author_id" LEFT OUTER JOIN "comments_tags" ON "comments_tags"."comment_id" = "comments"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "comments_tags"."tag_id" WHERE "comments"."approved" = ' + db_true + ' AND "author"."special" = ' + db_true
186+
end
175187

176188
assert_equal sql, records.to_sql
177189

@@ -190,13 +202,18 @@ def test_add_joins_with_sub_relationship
190202
records = Api::V10::PostResource.records({})
191203
records = join_manager.join(records, {})
192204

193-
sql = 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" LEFT OUTER JOIN "people" ON "people"."id" = "comments"."author_id" LEFT OUTER JOIN "comments_tags" ON "comments_tags"."comment_id" = "comments"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "comments_tags"."tag_id" LEFT OUTER JOIN "comments" "comments_people" ON "comments_people"."author_id" = "people"."id" WHERE "comments"."approved" = ' + db_true + ' AND "author"."special" = ' + db_true
205+
if (Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR >= 1) || Rails::VERSION::MAJOR > 6
206+
sql = 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" LEFT OUTER JOIN "people" author ON author."id" = "comments"."author_id" LEFT OUTER JOIN "comments_tags" ON "comments_tags"."comment_id" = "comments"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "comments_tags"."tag_id" LEFT OUTER JOIN "comments" "comments_people" ON "comments_people"."author_id" = "people"."id" WHERE "comments"."approved" = ' + db_true + ' AND "author"."special" = ' + db_true
207+
assert_hash_equals({alias: 'author', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:author)))
208+
else
209+
sql = 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" LEFT OUTER JOIN "people" ON "people"."id" = "comments"."author_id" LEFT OUTER JOIN "comments_tags" ON "comments_tags"."comment_id" = "comments"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "comments_tags"."tag_id" LEFT OUTER JOIN "comments" "comments_people" ON "comments_people"."author_id" = "people"."id" WHERE "comments"."approved" = ' + db_true + ' AND "author"."special" = ' + db_true
210+
assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:author)))
211+
end
194212

195213
assert_equal sql, records.to_sql
196214

197215
assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.source_join_details)
198216
assert_hash_equals({alias: 'comments', join_type: :inner}, join_manager.join_details_by_relationship(Api::V10::PostResource._relationship(:comments)))
199-
assert_hash_equals({alias: 'people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:author)))
200217
assert_hash_equals({alias: 'tags', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::CommentResource._relationship(:tags)))
201218
assert_hash_equals({alias: 'comments_people', join_type: :left}, join_manager.join_details_by_relationship(Api::V10::PersonResource._relationship(:comments)))
202219
end
@@ -263,7 +280,11 @@ def test_polymorphic_join_belongs_to_filter_on_resource
263280
records = PictureResource.records({})
264281
records = join_manager.join(records, {})
265282

266-
assert_equal 'SELECT "pictures".* FROM "pictures" LEFT OUTER JOIN "documents" ON "documents"."id" = "pictures"."imageable_id" AND "pictures"."imageable_type" = \'Document\' LEFT OUTER JOIN "products" ON "products"."id" = "pictures"."imageable_id" AND "pictures"."imageable_type" = \'Product\' LEFT OUTER JOIN "file_properties" ON "file_properties"."fileable_id" = "pictures"."id" AND "file_properties"."fileable_type" = \'Picture\'', records.to_sql
283+
#TODO: Fix this with a better test
284+
sql_v1 = 'SELECT "pictures".* FROM "pictures" LEFT OUTER JOIN "documents" ON "documents"."id" = "pictures"."imageable_id" AND "pictures"."imageable_type" = \'Document\' LEFT OUTER JOIN "products" ON "products"."id" = "pictures"."imageable_id" AND "pictures"."imageable_type" = \'Product\' LEFT OUTER JOIN "file_properties" ON "file_properties"."fileable_id" = "pictures"."id" AND "file_properties"."fileable_type" = \'Picture\''
285+
sql_v2 = 'SELECT "pictures".* FROM "pictures" LEFT OUTER JOIN "documents" ON "documents"."id" = "pictures"."imageable_id" AND "pictures"."imageable_type" = \'Document\' LEFT OUTER JOIN "products" ON "products"."id" = "pictures"."imageable_id" AND "pictures"."imageable_type" = \'Product\' LEFT OUTER JOIN "file_properties" ON "file_properties"."fileable_type" = \'Picture\' AND "file_properties"."fileable_id" = "pictures"."id"'
286+
assert records.to_sql == sql_v1 || records.to_sql == sql_v2, 'did not generate an expected sql statement'
287+
267288
assert_hash_equals({alias: 'pictures', join_type: :root}, join_manager.source_join_details)
268289
assert_hash_equals({alias: 'products', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'products'))
269290
assert_hash_equals({alias: 'documents', join_type: :left}, join_manager.join_details_by_polymorphic_relationship(PictureResource._relationship(:imageable), 'documents'))

test/unit/resource/resource_test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class PostWithBadAfterSave < ActiveRecord::Base
1313
after_save :do_some_after_save_stuff
1414

1515
def do_some_after_save_stuff
16-
errors[:base] << 'Boom! Error added in after_save callback.'
16+
errors.add(:base, 'Boom! Error added in after_save callback.')
1717
raise ActiveRecord::RecordInvalid.new(self)
1818
end
1919
end
@@ -23,7 +23,7 @@ class PostWithCustomValidationContext < ActiveRecord::Base
2323
validate :api_specific_check, on: :json_api_create
2424

2525
def api_specific_check
26-
errors[:base] << 'Record is invalid'
26+
errors.add(:base, 'Record is invalid')
2727
end
2828
end
2929

0 commit comments

Comments
 (0)