diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index aeb9b1ae9..8fd0da3c2 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -2,67 +2,26 @@ name: CI on: push: - branches: [ 'master', 'release-0-8', 'release-0-9', 'release-0-10' ] + branches: [ 'master' ] pull_request: branches: ['**'] jobs: tests: runs-on: ubuntu-latest - services: - postgres: - image: postgres - env: - POSTGRES_PASSWORD: password - POSTGRES_DB: test - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 5432:5432 strategy: fail-fast: false matrix: ruby: - - 2.6 - - 2.7 - - '3.0' - - 3.1 - - 3.2 + - '3.4' + - '3.3' + - '3.2' rails: - - 7.0.4 - - 6.1.7 - - 6.0.6 - - 5.2.8.1 - - 5.1.7 + - '7.1' + - '7.0' + - '8.0.2' database_url: - - postgresql://postgres:password@localhost:5432/test - sqlite3:test_db - exclude: - - ruby: 3.2 - rails: 6.0.6 - - ruby: 3.2 - rails: 5.2.8.1 - - ruby: 3.2 - rails: 5.1.7 - - ruby: 3.1 - rails: 6.0.6 - - ruby: 3.1 - rails: 5.2.8.1 - - ruby: 3.1 - rails: 5.1.7 - - ruby: '3.0' - rails: 6.0.6 - - ruby: '3.0' - rails: 5.2.8.1 - - ruby: '3.0' - rails: 5.1.7 - - ruby: 2.6 - rails: 7.0.4 - - database_url: postgresql://postgres:password@localhost:5432/test - rails: 5.1.7 env: RAILS_VERSION: ${{ matrix.rails }} DATABASE_URL: ${{ matrix.database_url }} @@ -73,7 +32,6 @@ jobs: uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - - name: Install dependencies - run: bundle install --jobs 4 --retry 3 + bundler-cache: true - name: Run tests run: bundle exec rake test diff --git a/Gemfile b/Gemfile index 2535d0200..f022a438b 100644 --- a/Gemfile +++ b/Gemfile @@ -10,12 +10,9 @@ version = ENV['RAILS_VERSION'] || 'default' platforms :ruby do gem 'pg' - - if version.start_with?('4.2', '5.0') - gem 'sqlite3', '~> 1.3.13' - else - gem 'sqlite3', '~> 1.4' - end + gem 'mysql2' + gem 'sqlite3' + gem 'csv' end case version @@ -26,4 +23,4 @@ when 'default' gem 'railties', '>= 6.0' else gem 'railties', "~> #{version}" -end \ No newline at end of file +end diff --git a/jsonapi-resources.gemspec b/jsonapi-resources.gemspec index eb3c67fa5..22745c81d 100644 --- a/jsonapi-resources.gemspec +++ b/jsonapi-resources.gemspec @@ -4,13 +4,13 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'jsonapi/resources/version' Gem::Specification.new do |spec| - spec.name = 'jsonapi-resources' + spec.name = 'sanger-jsonapi-resources' spec.version = JSONAPI::Resources::VERSION - spec.authors = ['Dan Gebhardt', 'Larry Gebhardt'] - spec.email = ['dan@cerebris.com', 'larry@cerebris.com'] + spec.authors = ['PSD Team - Wellcome Trust Sanger Institute'] + spec.email = ['psd@sanger.ac.uk'] spec.summary = 'Easily support JSON API in Rails.' - spec.description = 'A resource-centric approach to implementing the controllers, routes, and serializers needed to support the JSON API spec.' - spec.homepage = 'https://github.com/cerebris/jsonapi-resources' + spec.description = 'Forked from jsonapi-resources. A resource-centric approach to implementing the controllers, routes, and serializers needed to support the JSON API spec.' + spec.homepage = 'https://github.com/sanger/jsonapi-resources' spec.license = 'MIT' spec.files = Dir.glob("{bin,lib}/**/*") + %w(LICENSE.txt README.md) diff --git a/lib/generators/jsonapi/controller_generator.rb b/lib/generators/jsonapi/controller_generator.rb index 41ee4eb1e..d6aba8bf9 100644 --- a/lib/generators/jsonapi/controller_generator.rb +++ b/lib/generators/jsonapi/controller_generator.rb @@ -1,3 +1,4 @@ +require 'rails/generators' module Jsonapi class ControllerGenerator < Rails::Generators::NamedBase source_root File.expand_path('../templates', __FILE__) diff --git a/lib/generators/jsonapi/resource_generator.rb b/lib/generators/jsonapi/resource_generator.rb index 80aa24b4d..25feb14a1 100644 --- a/lib/generators/jsonapi/resource_generator.rb +++ b/lib/generators/jsonapi/resource_generator.rb @@ -1,3 +1,4 @@ +require 'rails/generators' module Jsonapi class ResourceGenerator < Rails::Generators::NamedBase source_root File.expand_path('../templates', __FILE__) diff --git a/lib/jsonapi/active_relation_resource.rb b/lib/jsonapi/active_relation_resource.rb index 581ed1e02..bfe88af26 100644 --- a/lib/jsonapi/active_relation_resource.rb +++ b/lib/jsonapi/active_relation_resource.rb @@ -666,10 +666,14 @@ def find_related_polymorphic_fragments(source_fragments, relationship, options, end relation_position = relation_positions[row[2].downcase.pluralize] - model_fields = relation_position[:model_fields] - cache_field = relation_position[:cache_field] - cache_offset = relation_position[:cache_offset] - field_offset = relation_position[:field_offset] + if relation_position + model_fields = relation_position[:model_fields] + cache_field = relation_position[:cache_field] + cache_offset = relation_position[:cache_offset] + field_offset = relation_position[:field_offset] + else + next # Skip processing if relation_position is nil + end if cache_field related_fragments[rid].cache = cast_to_attribute_type(row[cache_offset], cache_field[:type]) diff --git a/lib/jsonapi/acts_as_resource_controller.rb b/lib/jsonapi/acts_as_resource_controller.rb index e448fa0ea..8b29043d1 100644 --- a/lib/jsonapi/acts_as_resource_controller.rb +++ b/lib/jsonapi/acts_as_resource_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'csv' - +require_relative 'compatibility_helper' module JSONAPI module ActsAsResourceController MEDIA_TYPE_MATCHER = /.+".+"[^,]*|[^,]+/ @@ -63,16 +63,16 @@ def index_related_resources def get_related_resource # :nocov: - ActiveSupport::Deprecation.warn "In #{self.class.name} you exposed a `get_related_resource`"\ - " action. Please use `show_related_resource` instead." + JSONAPI::CompatibilityHelper.deprecation_warn("In #{self.class.name} you exposed a `get_related_resource`"\ + " action. Please use `show_related_resource` instead.") show_related_resource # :nocov: end def get_related_resources # :nocov: - ActiveSupport::Deprecation.warn "In #{self.class.name} you exposed a `get_related_resources`"\ - " action. Please use `index_related_resources` instead." + JSONAPI::CompatibilityHelper.deprecation_warn("In #{self.class.name} you exposed a `get_related_resources`"\ + " action. Please use `index_related_resources` instead.") index_related_resources # :nocov: end diff --git a/lib/jsonapi/basic_resource.rb b/lib/jsonapi/basic_resource.rb index 2eeba5c5d..d35ad796d 100644 --- a/lib/jsonapi/basic_resource.rb +++ b/lib/jsonapi/basic_resource.rb @@ -2,7 +2,7 @@ require 'jsonapi/callbacks' require 'jsonapi/configuration' - +require_relative 'compatibility_helper' module JSONAPI class BasicResource include Callbacks @@ -547,7 +547,7 @@ def attribute(attribute_name, options = {}) check_reserved_attribute_name(attr) if (attr == :id) && (options[:format].nil?) - ActiveSupport::Deprecation.warn('Id without format is no longer supported. Please remove ids from attributes, or specify a format.') + JSONAPI::CompatibilityHelper.deprecation_warn('Id without format is deprecated. Please specify a format for the id attribute.') end check_duplicate_attribute_name(attr) if options[:format].nil? @@ -609,11 +609,12 @@ def has_one(*attrs) end def belongs_to(*attrs) - ActiveSupport::Deprecation.warn "In #{name} you exposed a `has_one` relationship "\ + + JSONAPI::CompatibilityHelper.deprecation_warn( "In #{name} you exposed a `has_one` relationship "\ " using the `belongs_to` class method. We think `has_one`" \ " is more appropriate. If you know what you're doing," \ " and don't want to see this warning again, override the" \ - " `belongs_to` class method on your resource." + " `belongs_to` class method on your resource.") _add_relationship(Relationship::ToOne, *attrs) end diff --git a/lib/jsonapi/compatibility_helper.rb b/lib/jsonapi/compatibility_helper.rb new file mode 100644 index 000000000..516609349 --- /dev/null +++ b/lib/jsonapi/compatibility_helper.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +# JSONAPI::CompatibilityHelper +# +# This module provides a version-safe method for issuing deprecation warnings +# that works across multiple versions of Rails (7.x, 8.x, etc). +# +# Usage: +# JSONAPI::CompatibilityHelper.deprecation_warn("Your deprecation message") +# +# The method will use the public `warn` method if available, otherwise it will +# use `send(:warn, ...)` to maintain compatibility with Rails 8+ where `warn` +# is private. +# +# Example: +# JSONAPI::CompatibilityHelper.deprecation_warn("This feature is deprecated.") + +module JSONAPI + module CompatibilityHelper + def deprecation_warn(message) + if ActiveSupport::Deprecation.respond_to?(:warn) && ActiveSupport::Deprecation.public_method_defined?(:warn) + ActiveSupport::Deprecation.warn(message) + else + ActiveSupport::Deprecation.send(:warn, message) + end + end + module_function :deprecation_warn + end +end diff --git a/lib/jsonapi/configuration.rb b/lib/jsonapi/configuration.rb index 6cd5d8e1b..e1a7e1c61 100644 --- a/lib/jsonapi/configuration.rb +++ b/lib/jsonapi/configuration.rb @@ -3,7 +3,7 @@ require 'jsonapi/formatter' require 'jsonapi/processor' require 'concurrent' - +require_relative 'compatibility_helper' module JSONAPI class Configuration attr_reader :json_key_format, @@ -227,7 +227,7 @@ def exception_class_allowed?(e) end def default_processor_klass=(default_processor_klass) - ActiveSupport::Deprecation.warn('`default_processor_klass` has been replaced by `default_processor_klass_name`.') + JSONAPI::CompatibilityHelper.deprecation_warn('`default_processor_klass` has been replaced by `default_processor_klass_name`.') @default_processor_klass = default_processor_klass end @@ -241,18 +241,18 @@ def default_processor_klass_name=(default_processor_klass_name) end def allow_include=(allow_include) - ActiveSupport::Deprecation.warn('`allow_include` has been replaced by `default_allow_include_to_one` and `default_allow_include_to_many` options.') + JSONAPI::CompatibilityHelper.deprecation_warn('`allow_include` has been replaced by `default_allow_include_to_one` and `default_allow_include_to_many` options.') @default_allow_include_to_one = allow_include @default_allow_include_to_many = allow_include end def whitelist_all_exceptions=(allow_all_exceptions) - ActiveSupport::Deprecation.warn('`whitelist_all_exceptions` has been replaced by `allow_all_exceptions`') + JSONAPI::CompatibilityHelper.deprecation_warn('`whitelist_all_exceptions` has been replaced by `allow_all_exceptions`') @allow_all_exceptions = allow_all_exceptions end def exception_class_whitelist=(exception_class_allowlist) - ActiveSupport::Deprecation.warn('`exception_class_whitelist` has been replaced by `exception_class_allowlist`') + JSONAPI::CompatibilityHelper.deprecation_warn('`exception_class_whitelist` has been replaced by `exception_class_allowlist`') @exception_class_allowlist = exception_class_allowlist end diff --git a/lib/jsonapi/relationship.rb b/lib/jsonapi/relationship.rb index 8824fc65d..62c17d9c8 100644 --- a/lib/jsonapi/relationship.rb +++ b/lib/jsonapi/relationship.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require_relative 'compatibility_helper' module JSONAPI class Relationship attr_reader :acts_as_set, :foreign_key, :options, :name, @@ -21,7 +21,7 @@ def initialize(name, options = {}) @polymorphic = options.fetch(:polymorphic, false) == true @polymorphic_types = options[:polymorphic_types] if options[:polymorphic_relations] - ActiveSupport::Deprecation.warn('Use polymorphic_types instead of polymorphic_relations') + JSONAPI::CompatibilityHelper.deprecation_warn('Use polymorphic_types instead of polymorphic_relations') @polymorphic_types ||= options[:polymorphic_relations] end diff --git a/lib/jsonapi/resource.rb b/lib/jsonapi/resource.rb index 4d34dd290..421b46ea2 100644 --- a/lib/jsonapi/resource.rb +++ b/lib/jsonapi/resource.rb @@ -4,4 +4,4 @@ module JSONAPI class Resource < ActiveRelationResource root_resource end -end \ No newline at end of file +end diff --git a/lib/jsonapi/resources/version.rb b/lib/jsonapi/resources/version.rb index fb4178797..26eda26ad 100644 --- a/lib/jsonapi/resources/version.rb +++ b/lib/jsonapi/resources/version.rb @@ -1,5 +1,5 @@ module JSONAPI module Resources - VERSION = '0.11.0.beta1' + VERSION = '0.2.0' end end diff --git a/lib/sanger-jsonapi-resources.rb b/lib/sanger-jsonapi-resources.rb new file mode 100644 index 000000000..2b4763cf6 --- /dev/null +++ b/lib/sanger-jsonapi-resources.rb @@ -0,0 +1,7 @@ +# As we are packaging 'sanger-jsonapi-resources' as a separate gem, RubyGems expects +# the main file to be 'lib/sanger-jsonapi-resources.rb' to match the gem name. +# Without this file, requiring the gem or Rails autoloading would fail, even if the internal code is unchanged. +# This file exists to ensure compatibility with RubyGems and Bundler. +# The easiest solution is to use this wrapper file, which simply requires the original 'jsonapi-resources' code, +# so all internal references and modules remain unchanged and compatible. +require_relative 'jsonapi-resources' diff --git a/test/fixtures/active_record.rb b/test/fixtures/active_record.rb index 1209302fd..e6866785c 100644 --- a/test/fixtures/active_record.rb +++ b/test/fixtures/active_record.rb @@ -52,7 +52,7 @@ end create_table :posts, force: true do |t| - t.string :title, length: 255 + t.string :title, limit: 255 t.text :body t.integer :author_id t.integer :parent_post_id @@ -85,17 +85,20 @@ end create_table :posts_tags, force: true do |t| - t.references :post, :tag, index: true + t.references :post, index:true + t.references :tag, index:true end add_index :posts_tags, [:post_id, :tag_id], unique: true create_table :special_post_tags, force: true do |t| - t.references :post, :tag, index: true + t.references :post, index: true + t.references :tag, index: true end add_index :special_post_tags, [:post_id, :tag_id], unique: true create_table :comments_tags, force: true do |t| - t.references :comment, :tag, index: true + t.references :comment, index: true + t.references :tag, index: true end create_table :iso_currencies, id: false, force: true do |t| @@ -324,8 +327,8 @@ create_table :related_things, force: true do |t| t.string :name - t.references :from, references: :thing - t.references :to, references: :thing + t.references :from, foreign_key: { to_table: :things } + t.references :to, foreign_key: { to_table: :things } t.timestamps null: false end diff --git a/test/test_helper.rb b/test/test_helper.rb index 9850a49c6..f6f9c1b70 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -23,7 +23,6 @@ ENV['DATABASE_URL'] ||= "sqlite3:test_db" require 'active_record/railtie' -require 'rails/test_help' require 'minitest/mock' require 'jsonapi-resources' require 'pry' @@ -42,7 +41,11 @@ config.json_key_format = :camelized_key end -ActiveSupport::Deprecation.silenced = true +if ActiveSupport::Deprecation.respond_to?(:behavior=) + ActiveSupport::Deprecation.behavior = :silence +elsif ActiveSupport::Deprecation.respond_to?(:silenced=) + ActiveSupport::Deprecation.silenced = true +end puts "Testing With RAILS VERSION #{Rails.version}" @@ -457,12 +460,12 @@ def run_in_transaction? true end - self.fixture_path = "#{Rails.root}/fixtures" + self.fixture_paths = ["#{Rails.root}/fixtures"] fixtures :all end class ActiveSupport::TestCase - self.fixture_path = "#{Rails.root}/fixtures" + self.fixture_paths = ["#{Rails.root}/fixtures"] fixtures :all setup do @routes = TestApp.routes @@ -470,7 +473,7 @@ class ActiveSupport::TestCase end class ActionDispatch::IntegrationTest - self.fixture_path = "#{Rails.root}/fixtures" + self.fixture_paths = ["#{Rails.root}/fixtures"] fixtures :all def assert_jsonapi_response(expected_status, msg = nil)