0.0
Repository is archived
No commit activity in last 3 years
No release in over 3 years
A library of Ruby classes to help create consistent data interfaces
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 10.1
~> 3.3
 Project Readme

data-provider

Ruby gem that provides a set of classes to build consistent data interfaces

Build Status Code Health

Installation

Rubygems:

gem install data-provider

Bundler:

gem 'data-provider'

Examples

Define a provider class with some providers

require 'data_provider'

class BookProvider
	include DataProvider::Base
	
	# quick syntax for 'simple' providers
	provides({
		title: 'The Monkey Wrench Gang',
		author: 'Edward Abbey'
	})
	
	# longer syntax for more complicated providers
	provider :display_title do
		"#{take(:author)} - #{take(:title)}"
	end

	provider :price do
		9.99
	end
end

Using a provider class

book_provider = BookProvider.new()
book_provider.take(:title) # => 'The Monkey Wrench Gang'
book_provider.take(:author) # => 'Edward Abbey'
book_provider.take(:display_title) # => 'Edward Abbey - The Monkey Wrench Gang'
book_provider.take(:price) # => 9.99

Data providers can be given data to customize their output

require 'data_provider'

class ProductProvider
	include DataProvider::Base
	
	provider :normal_price do
		17.99
	end
	
	provider :discount_price do
		take(:normal_price) - get_data(:discount)
	end
end

product_provider = ProductProvider.new
product_provider.take(:normal_price) # => 17.99
product_provider.take(:discount_price) # => TypeError (discount data not given,): nil can't be coerced into Float
discounted_provider = product_provider.add_data(discount: 3.0) # returns a new instance of the same provider class
discounted_provider.take(:discount_price) # => 14.99
product_provider.take(:discount_price) # => TypeError (this instance didn't get the new data)
product_provider.add_data!(discount: 2) # => Updates this instance instead of creating a new one
product_provider.take(:discount_price) # => 15.99
product_provider.add_data!(discount: 4).take(:discount_price) #=> 13.99

Providers can be defined in a module and added to a provider class using the add class-method (not using include!)

require 'data-provider'

module BandInfo
	include DataProvider::Base
	
	provider :band do
		'D4'
	end
	
	provider :bassPlayer do
		'Paddy'
	end
end

class Band
	include DataProvider::Base
	
	provider :band do
		'Dillinger Four'
	end
	
	provider :drummer do
		'Lane Pederson'
	end

	add BandInfo # note: add, not include!
end

band = Band.new
band.take(:band) # => 'D4', class provider was overwritten when the module got added
band.take(:bassPlayer) # => 'Paddy'
band.take(:drummer) #=> 'Lane Pederson'

Provider identifiers don't have to be symbols, they can be anything. Specifically array identifiers are suitable for creating data providers for hierarchical systems

require 'data_provider'

module AlbumProvider
	include DataProvider::Base
	
	provides({
		title: 'Reinventing Axle Rose',
		band: 'Against Me!'
		[:band, :hometown] => 'Gainesville, FL'
	})
end

class Catalog
	include DataProvider::Base
	
	provider [:music, :album, :bandname] do
		# scoped_take is a method only available inside provider blocks,
		# it lets a provider access other providers in the same 'scope',
		# which means provider whose array-identifiers start with the same values,
		# in this case the scope is [:music, :album]
		scoped_take(:band).upcase
	end

	# by using `add_scoped` all providers of the added module, will be
	# turned into array and prefixed with the given scope
	add_scoped AlbumProvider, :scope => [:music, :album]
end

catalog = Catalog.new
catalog.take(:title) # => DataProvider::ProviderMissingException
catalog.take([:music, :album, :title]) # => 'Reinventing Axle Rose'
catalog.take([:music, :album, :band, :hometown]) # => 'Gainesville, FL'
catalog.take([:music, :album, :bandname]) # => 'AGAINST ME!"