Jsonapi-resources: Custom top level meta in index

Created on 23 May 2017  路  1Comment  路  Source: cerebris/jsonapi-resources

Hi, how can I pass a custom data to top level meta in index requests?
I was trying with:

def self.meta(options)
 {a: 1}
end

but its not working :/

Most helpful comment

you can define your on top level meta like this:

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', require: false

  if ENV['JSONAPI_RESOURCES_PG']
    gem 'pg'
  else
    gem 'sqlite3', platform: :mri
    gem 'activerecord-jdbcsqlite3-adapter',
        git: 'https://github.com/jruby/activerecord-jdbc-adapter',
        branch: 'rails-5',
        platform: :jruby
  end

  if ENV['JSONAPI_RESOURCES_PATH']
    gem 'jsonapi-resources', path: ENV['JSONAPI_RESOURCES_PATH'], require: false
  else
    gem 'jsonapi-resources', git: 'https://github.com/cerebris/jsonapi-resources', require: false
  end

end

# prepare active_record database
require 'active_record'

class NullLogger < Logger
  def initialize(*_args)
  end

  def add(*_args, &_block)
  end
end

if ENV['JSONAPI_RESOURCES_PG']
  db_name = ENV['JSONAPI_RESOURCES_PG']
  system("psql -c 'DROP DATABASE IF EXISTS #{db_name};'")
  system("psql -c 'CREATE DATABASE #{db_name};'")
  ActiveRecord::Base.establish_connection(adapter: 'postgresql', database: db_name)
else
  ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
end

ActiveRecord::Base.logger = ENV['SILENT'] ? NullLogger.new : Logger.new(STDOUT)
ActiveRecord::Migration.verbose = !ENV['SILENT']

ActiveRecord::Schema.define do
  # Add your schema here
  create_table :reviews, force: true do |t|
    t.string :content
  end

  create_table :authors, force: true do |t|
    t.string :name
  end
end

# create models
class Review < ActiveRecord::Base
end

class Author < ActiveRecord::Base
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 ReviewsController < ApplicationController
  include JSONAPI::ActsAsResourceController
end

class AuthorsController < ApplicationController
  include JSONAPI::ActsAsResourceController
end

class ReviewResource < JSONAPI::Resource
  attribute :content

  def self.top_level_meta(_options)
    { foo: 'bar' }
  end
end

class AuthorResource < JSONAPI::Resource
  attribute :name
end

class CustomProcessor < JSONAPI::Processor
  after_find do
    if @resource_klass.respond_to?(:top_level_meta)
      @result.meta.merge! @resource_klass.top_level_meta(context: context)
    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
  config.default_processor_klass = CustomProcessor
end

# draw routes
Rails.application.routes.draw do
  jsonapi_resources :reviews, only: :index
  jsonapi_resources :authors, only: :index
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 test_reviews_has_meta
    get '/reviews', nil, json_api_headers
    assert last_response.ok?
    expected_meta = { foo: 'bar' }
    assert_equal expected_meta, last_response_json[:meta]
  end

  def test_authors_has_no_meta
    get '/authors', nil, json_api_headers
    assert last_response.ok?
    assert_equal false, last_response_json.has_key?(:meta)
  end

  private

  def json_api_headers
    {'Accept' => JSONAPI::MEDIA_TYPE, 'CONTENT_TYPE' => JSONAPI::MEDIA_TYPE}
  end

  def last_response_json
    JSON.parse(last_response.body).deep_symbolize_keys
  end

  def app
    Rails.application
  end
end

>All comments

you can define your on top level meta like this:

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', require: false

  if ENV['JSONAPI_RESOURCES_PG']
    gem 'pg'
  else
    gem 'sqlite3', platform: :mri
    gem 'activerecord-jdbcsqlite3-adapter',
        git: 'https://github.com/jruby/activerecord-jdbc-adapter',
        branch: 'rails-5',
        platform: :jruby
  end

  if ENV['JSONAPI_RESOURCES_PATH']
    gem 'jsonapi-resources', path: ENV['JSONAPI_RESOURCES_PATH'], require: false
  else
    gem 'jsonapi-resources', git: 'https://github.com/cerebris/jsonapi-resources', require: false
  end

end

# prepare active_record database
require 'active_record'

class NullLogger < Logger
  def initialize(*_args)
  end

  def add(*_args, &_block)
  end
end

if ENV['JSONAPI_RESOURCES_PG']
  db_name = ENV['JSONAPI_RESOURCES_PG']
  system("psql -c 'DROP DATABASE IF EXISTS #{db_name};'")
  system("psql -c 'CREATE DATABASE #{db_name};'")
  ActiveRecord::Base.establish_connection(adapter: 'postgresql', database: db_name)
else
  ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
end

ActiveRecord::Base.logger = ENV['SILENT'] ? NullLogger.new : Logger.new(STDOUT)
ActiveRecord::Migration.verbose = !ENV['SILENT']

ActiveRecord::Schema.define do
  # Add your schema here
  create_table :reviews, force: true do |t|
    t.string :content
  end

  create_table :authors, force: true do |t|
    t.string :name
  end
end

# create models
class Review < ActiveRecord::Base
end

class Author < ActiveRecord::Base
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 ReviewsController < ApplicationController
  include JSONAPI::ActsAsResourceController
end

class AuthorsController < ApplicationController
  include JSONAPI::ActsAsResourceController
end

class ReviewResource < JSONAPI::Resource
  attribute :content

  def self.top_level_meta(_options)
    { foo: 'bar' }
  end
end

class AuthorResource < JSONAPI::Resource
  attribute :name
end

class CustomProcessor < JSONAPI::Processor
  after_find do
    if @resource_klass.respond_to?(:top_level_meta)
      @result.meta.merge! @resource_klass.top_level_meta(context: context)
    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
  config.default_processor_klass = CustomProcessor
end

# draw routes
Rails.application.routes.draw do
  jsonapi_resources :reviews, only: :index
  jsonapi_resources :authors, only: :index
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 test_reviews_has_meta
    get '/reviews', nil, json_api_headers
    assert last_response.ok?
    expected_meta = { foo: 'bar' }
    assert_equal expected_meta, last_response_json[:meta]
  end

  def test_authors_has_no_meta
    get '/authors', nil, json_api_headers
    assert last_response.ok?
    assert_equal false, last_response_json.has_key?(:meta)
  end

  private

  def json_api_headers
    {'Accept' => JSONAPI::MEDIA_TYPE, 'CONTENT_TYPE' => JSONAPI::MEDIA_TYPE}
  end

  def last_response_json
    JSON.parse(last_response.body).deep_symbolize_keys
  end

  def app
    Rails.application
  end
end
Was this page helpful?
0 / 5 - 0 ratings