Last active
September 25, 2019 23:34
-
-
Save arcreative/2f338dd8915c3a76f63f63d36830937c to your computer and use it in GitHub Desktop.
JSONAPI::Resources failure when trying to include models on a polymorphic association
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
begin | |
require 'bundler/inline' | |
require 'bundler' | |
rescue LoadError => e | |
STDERR.puts 'Bundler version 1.10 or later is required. Please update your Bundler' | |
raise e | |
end | |
gemfile(true, ui: ENV['SILENT'] ? Bundler::UI::Silent.new : Bundler::UI::Shell.new) do | |
source 'https://rubygems.org' | |
gem 'rails', '~> 5.2.3', require: false | |
gem 'sqlite3', platform: :mri | |
gem 'audited', '~> 4.9.0' | |
gem 'activerecord-jdbcsqlite3-adapter', | |
git: 'https://github.com/jruby/activerecord-jdbc-adapter', | |
# branch: 'rails-5', | |
platform: :jruby | |
if ENV['JSONAPI_RESOURCES_PATH'] | |
gem 'jsonapi-resources', path: ENV['JSONAPI_RESOURCES_PATH'], require: false | |
else | |
gem 'jsonapi-resources', '~> 0.9.10', require: false | |
end | |
end | |
# prepare active_record database | |
require 'active_record' | |
class NullLogger < Logger | |
def initialize(*_args) | |
end | |
def add(*_args, &_block) | |
end | |
end | |
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:') | |
ActiveRecord::Base.logger = ENV['SILENT'] ? NullLogger.new : Logger.new(STDOUT) | |
ActiveRecord::Migration.verbose = !ENV['SILENT'] | |
ActiveRecord::Schema.define do | |
create_table "users", force: :cascade do |t| | |
t.string "name", null: false | |
end | |
create_table "roles", force: :cascade do |t| | |
t.string "name", null: false | |
end | |
create_table "role_applications", force: :cascade do |t| | |
t.integer "role_id", null: false | |
t.integer "applicant_id", null: false | |
t.string "state", null: false, default: 'pending' | |
t.index ["applicant_id"], name: "index_role_applications_on_applicant_id" | |
t.index ["role_id", "applicant_id"], name: "index_role_applications_on_role_id_and_applicant_id", unique: true | |
t.index ["role_id"], name: "index_role_applications_on_role_id" | |
end | |
create_table "audits", force: :cascade do |t| | |
t.integer "auditable_id" | |
t.string "auditable_type" | |
t.integer "associated_id" | |
t.string "associated_type" | |
t.integer "user_id" | |
t.string "user_type" | |
t.string "username" | |
t.string "action" | |
t.text "audited_changes" | |
t.integer "version", default: 0 | |
t.string "comment" | |
t.string "remote_address" | |
t.string "request_uuid" | |
t.datetime "created_at" | |
t.index ["associated_id", "associated_type"], name: "associated_index" | |
t.index ["auditable_id", "auditable_type"], name: "auditable_index" | |
t.index ["created_at"], name: "index_audits_on_created_at" | |
t.index ["request_uuid"], name: "index_audits_on_request_uuid" | |
t.index ["user_id", "user_type"], name: "user_index" | |
end | |
end | |
# create models | |
class ApplicationModel < ActiveRecord::Base | |
self.abstract_class = true | |
audited | |
end | |
class Role < ApplicationModel | |
has_many :applications, class_name: 'RoleApplication' | |
end | |
class RoleApplication < ApplicationModel | |
belongs_to :applicant, class_name: 'User' | |
belongs_to :role | |
enum state: { pending: 'pending', foo: 'foo', bar: 'bar', baz: 'baz' } | |
end | |
class User < ApplicationModel | |
has_many :applications, class_name: 'RoleApplication', foreign_key: :applicant_id | |
end | |
# prepare rails app | |
require 'action_controller/railtie' | |
# require 'action_view/railtie' | |
require 'jsonapi-resources' | |
class ApplicationController < ActionController::Base | |
end | |
# prepare jsonapi resources and controllers | |
class ApiController < ApplicationController | |
include JSONAPI::ActsAsResourceController | |
end | |
module Api | |
module V1 | |
class AuditsController < ApiController; end | |
class RolesController < ApiController; end | |
class RoleApplicationsController < ApiController; end | |
class UsersController < ApiController; end | |
class AuditResource < JSONAPI::Resource | |
model_name 'Audited::Audit' | |
has_one :auditable, polymorphic: true | |
end | |
class RoleResource < JSONAPI::Resource | |
has_many :applications | |
end | |
class RoleApplicationResource < JSONAPI::Resource | |
has_one :role | |
has_one :applicant | |
end | |
class UserResource < JSONAPI::Resource | |
has_many :applications | |
end | |
end | |
end | |
class TestApp < Rails::Application | |
config.root = File.dirname(__FILE__) | |
config.logger = ENV['SILENT'] ? NullLogger.new : Logger.new(STDOUT) | |
Rails.logger = config.logger | |
secrets.secret_token = 'secret_token' | |
secrets.secret_key_base = 'secret_key_base' | |
config.eager_load = false | |
end | |
# initialize app | |
Rails.application.initialize! | |
JSONAPI.configure do |config| | |
config.json_key_format = :underscored_key | |
config.route_format = :underscored_key | |
end | |
# draw routes | |
Rails.application.routes.draw do | |
namespace :api do | |
namespace :v1 do | |
jsonapi_resources :audits, only: [:index, :show] | |
jsonapi_resources :roles, only: [:index, :show] | |
jsonapi_resources :role_applications, only: [:index, :show] | |
jsonapi_resources :users, only: [:index, :show] | |
end | |
end | |
end | |
# prepare tests | |
require 'minitest/autorun' | |
require 'rack/test' | |
# Replace this with the code necessary to make your test fail. | |
class BugTest < Minitest::Test | |
include Rack::Test::Methods | |
def json_api_headers | |
{'Accept' => JSONAPI::MEDIA_TYPE, 'CONTENT_TYPE' => JSONAPI::MEDIA_TYPE} | |
end | |
def test_index_your_models | |
applicant = User.create! id: 1, name: 'Testy Testerson' | |
role = Role.create! id: 1, name: 'Some random role' | |
application = RoleApplication.create! id: 1, role: role, applicant: applicant | |
application.update(state: :foo) | |
application.update(state: :bar) | |
application.update(state: :baz) | |
assert application.reload.audits.count == 4 | |
get '/api/v1/audits', nil, json_api_headers | |
assert last_response.ok? | |
json_response = JSON.parse(last_response.body) | |
refute_nil json_response['data'] | |
refute_empty json_response['data'] | |
refute_empty json_response['data'].first | |
# Should fail | |
get '/api/v1/audits?include=auditable', nil, json_api_headers | |
end | |
private | |
def app | |
Rails.application | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment