Allow "if: Proc..." on link (#15)

This commit is contained in:
Brad Grzesiak 2019-10-25 08:32:56 -05:00 committed by Kevin Pheasey
parent 587fb2c5fe
commit ddc261d8dc
6 changed files with 70 additions and 46 deletions

View File

@ -1,29 +1,5 @@
require 'fast_jsonapi/scalar'
module FastJsonapi
class Attribute
attr_reader :key, :method, :conditional_proc
def initialize(key:, method:, options: {})
@key = key
@method = method
@conditional_proc = options[:if]
end
def serialize(record, serialization_params, output_hash)
if include_attribute?(record, serialization_params)
output_hash[key] = if method.is_a?(Proc)
method.arity.abs == 1 ? method.call(record) : method.call(record, serialization_params)
else
record.public_send(method)
end
end
end
def include_attribute?(record, serialization_params)
if conditional_proc.present?
conditional_proc.call(record, serialization_params)
else
true
end
end
end
class Attribute < Scalar; end
end

View File

@ -1,18 +1,5 @@
require 'fast_jsonapi/scalar'
module FastJsonapi
class Link
attr_reader :key, :method
def initialize(key:, method:)
@key = key
@method = method
end
def serialize(record, serialization_params, output_hash)
output_hash[key] = if method.is_a?(Proc)
method.arity == 1 ? method.call(record) : method.call(record, serialization_params)
else
record.public_send(method)
end
end
end
class Link < Scalar; end
end

View File

@ -285,14 +285,19 @@ module FastJsonapi
{}
end
def link(link_name, link_method_name = nil, &block)
# def link(link_name, link_method_name = nil, &block)
def link(*params, &block)
self.data_links = {} if self.data_links.nil?
link_method_name = link_name if link_method_name.nil?
options = params.last.is_a?(Hash) ? params.pop : {}
link_name = params.first
link_method_name = params[-1]
key = run_key_transform(link_name)
self.data_links[key] = Link.new(
key: key,
method: block || link_method_name
method: block || link_method_name,
options: options
)
end

View File

@ -0,0 +1,29 @@
module FastJsonapi
class Scalar
attr_reader :key, :method, :conditional_proc
def initialize(key:, method:, options: {})
@key = key
@method = method
@conditional_proc = options[:if]
end
def serialize(record, serialization_params, output_hash)
if conditionally_allowed?(record, serialization_params)
output_hash[key] = if method.is_a?(Proc)
method.arity.abs == 1 ? method.call(record) : method.call(record, serialization_params)
else
record.public_send(method)
end
end
end
def conditionally_allowed?(record, serialization_params)
if conditional_proc.present?
conditional_proc.call(record, serialization_params)
else
true
end
end
end
end

View File

@ -407,6 +407,26 @@ describe FastJsonapi::ObjectSerializer do
expect(action_serializable_hash[:data][:links][:url]).to eq "/action-movie/#{movie.id}"
end
end
describe 'optional links' do
subject(:downloadable_serializable_hash) { OptionalDownloadableMovieSerializer.new(movie, params).serializable_hash }
context 'when the link is provided' do
let(:params) { { params: { signed_url: signed_url } } }
let(:signed_url) { 'http://example.com/download_link?signature=abcdef' }
it 'includes the link' do
expect(downloadable_serializable_hash[:data][:links][:download]).to eq signed_url
end
end
context 'when the link is not provided' do
let(:params) { { params: {} } }
it 'does not include the link' do
expect(downloadable_serializable_hash[:data][:links]).to_not have_key(:download)
end
end
end
end
describe '#key_transform' do

View File

@ -197,6 +197,12 @@ RSpec.shared_context 'movie class' do
link(:url) { |object| "/horror-movie/#{object.id}" }
end
class OptionalDownloadableMovieSerializer < MovieSerializer
link(:download, if: Proc.new { |record, params| params && params[:signed_url] }) do |movie, params|
params[:signed_url]
end
end
class MovieWithoutIdStructSerializer
include FastJsonapi::ObjectSerializer
attributes :name, :release_year
@ -385,6 +391,7 @@ RSpec.shared_context 'movie class' do
ActionMovieSerializer
GenreMovieSerializer
HorrorMovieSerializer
OptionalDownloadableMovieSerializer
Movie
MovieSerializer
Actor