Module: Arstotzka
- Extended by:
- ActiveSupport::Concern, Sinclair::Configurable
- Defined in:
- lib/arstotzka.rb,
lib/arstotzka/base.rb,
lib/arstotzka/config.rb,
lib/arstotzka/reader.rb,
lib/arstotzka/crawler.rb,
lib/arstotzka/fetcher.rb,
lib/arstotzka/options.rb,
lib/arstotzka/version.rb,
lib/arstotzka/wrapper.rb,
lib/arstotzka/exception.rb,
lib/arstotzka/type_cast.rb,
lib/arstotzka/key_reader.rb,
lib/arstotzka/hash_reader.rb,
lib/arstotzka/key_changer.rb,
lib/arstotzka/class_methods.rb,
lib/arstotzka/fetcher/cache.rb,
lib/arstotzka/method_builder.rb,
lib/arstotzka/post_processor.rb,
lib/arstotzka/fetcher_builder.rb
Overview
Concern that enables the translation of domain though the usage of the class method expose
Examples:
json = <<-JSON
{
"person": {
"fullName": "Kelly Khan",
"age": 32,
"gender": "woman"
},
"collections": {
"cars": [{
"maker": "Volkswagen",
"model": "Jetta",
"units": [{
"nickName": "Betty",
"year": 2013
}, {
"nickName": "Roger",
"year": 2014
}]
}, {
"maker": "Ferrari",
"model": "Ferrari X1",
"units": [{
"nickName": "Geronimo",
"year": 2014
}]
}, {
"maker": "Fiat",
"model": "Uno",
"units": [{
"year": 1998
}]
}],
"games":[{
"producer": "Lucas Pope",
"titles": [{
"name": "papers, please",
"played": "10.2%"
}, {
"name": "TheNextBigThing",
"played": "100%"
}]
}, {
"producer": "Nintendo",
"titles": [{
"name": "Zelda",
"played": "90%"
}]
}, {
"producer": "BadCompany"
}]
}
}
JSON
hash = JSON.parse(json)
class Collector
include Arstotzka
MALE = 'male'
FEMALE= 'female'
attr_reader :hash
expose :full_name, :age, path: :person, json: :hash
expose :gender, path: :person, type: :gender, cached: true, json: :hash
def initialize(hash = {})
@hash = hash
end
end
module Arstotzka
module TypeCast
def to_gender(value)
case value
when 'man'
Collector::MALE
when 'woman'
Collector::FEMALE
else
raise 'invalid gender'
end
end
end
end
collector = Collector.new(hash)
collector.full_name # returns 'Kelly Khan'
collector.age # returns 32
collector.gender # returns Collector::FEMALE
hash['person']['fullName'] = 'Robert'
collector.full_name # returns 'Robert'
hash['person']['gender'] = 'man'
collector.gender # returns Collector::FEMALE as it was cached
class Collector
expose :car_names, flatten: true, compact: false, json: :hash,
default: 'MissingName',
full_path: 'collections.cars.units.nick_name'
end
collector = Collector.new(hash)
collector.car_names # returns [
# 'Betty', 'Roger',
# 'Geronimo', 'MissingName'
# ]
class Collector
class Game
include Arstotzka
attr_reader :json
expose :name
expose :played, type: :float
def initialize(json)
@json = json
end
def finished?
played > 85.0
end
end
end
class Collector
expose :finished_games, json: :hash,
flatten: true, klass: Collector::Game,
after: :filter_finished, compact: true,
full_path: 'collections.games.titles'
private
def filter_finished(games)
games.select(&:finished?)
end
end
collector = Collector.new(hash)
collector.finished_games # returns [
# Collector::Game.new(name: "TheNextBigThing", played: 100.0),
# Collector::Game.new(name: "Zelda", played: 90.0)
# ]
Using options klass and after
class Customer
attr_reader :name, :age
def initialize(name:, age:)
@name = name
@age = age
end
def adult?
age >= 18
end
end
class Store
include Arstotzka
expose :customers, klass: Customer, after: :filter_adults
def initialize(json)
@json = json
end
private
attr_reader :json
def filter_adults(values)
values.select(&:adult?)
end
end
hash = {
customers: [{
name: 'John', age: 21
}, {
name: 'Julia', age: 15
}, {
name: 'Carol', age: 22
}, {
name: 'Bobby', age: 12
}]
}
instance = Store.new(hash)
instance.customers # returns [
# Customer.new(name: 'John', age: 21),
# Customer.new(name: 'Carol', age: 22)
# ]
Using type with klass and after_each
module Arstotzka::TypeCast
def to_symbolized_hash(value)
value.symbolize_keys
end
end
class Drink
attr_reader :name, :price
def initialize(name:, price:)
@name = name
@price = price
end
def inflate(inflation)
@price = (price * (1 + inflation)).round(2)
end
end
class Bar
include Arstotzka
expose :drinks, type: :symbolized_hash,
klass: Drink, after_each: :add_inflation
def initialize(json)
@json = json
end
private
attr_reader :json
def add_inflation(drink)
drink.inflate(0.1)
drink
end
end
json = '{"drinks":[{"name":"tequila","price":7.50},{ "name":"vodka","price":5.50}]}'
hash = JSON.parse(hash)
instance = Bar.new(hash)
instance.drinks # returns [
# Drink.new(name: 'tequila', price: 8.25),
# Drink.new(name: 'vodka', price: 6.05)
# ]
Using cached, compact, after and full_path
class Person
attr_reader :name
def initialize(name)
@name = name
end
end
class Application
include Arstotzka
expose :users, full_path: 'users.first_name',
compact: true, cached: true,
after: :create_person
def initialize(json)
@json = json
end
private
attr_reader :json
def create_person(names)
names.map do |name|
warn "Creating person #{name}"
Person.new(name)
end
end
end
# Keys are on camel case (lower camel case)
hash = {
users: [
{ firstName: 'Lucy', email: '[email protected]' },
{ firstName: 'Bobby', email: '[email protected]' },
{ email: '[email protected]' },
{ firstName: 'Arthur', email: '[email protected]' }
]
}
instance = Application.new(hash)
instance.users # trigers the warn "Creating person <name>" 3 times
# returns [
# Person.new('Lucy'),
# Person.new('Bobby'),
# Person.new('Arthur')
# ]
instance.users # returns the same value, without triggering warn
Working with snake case hash
class JobSeeker
include Arstotzka
expose :applicants, case: :snake, default: 'John Doe',
full_path: 'applicants.full_name',
compact: true, json: :@hash
def initialize(hash)
@hash = hash
end
end
hash = {
'applicants' => [
{
'full_name' => 'Robert Hatz',
'email' => '[email protected]'
}, {
'full_name' => 'Marina Wantz',
'email' => '[email protected]'
}, {
'email' => '[email protected]'
}
]
}
instance = JobSeeker.new(hash)
instance.applicants # returns [
# 'Robert Hatz',
# 'Marina Wantz',
# 'John Doe'
# ]
Deep path with flatten option
class ShoppingMall
include Arstotzka
expose :customers, path: 'floors.stores',
flatten: true, json: :hash
def initialize(hash)
@hash = hash
end
private
attr_reader :hash
end
hash = {
floors: [{
name: 'ground', stores: [{
name: 'Starbucks', customers: %w[
John Bobby Maria
]
}, {
name: 'Pizza Hut', customers: %w[
Danny LJ
]
}]
}, {
name: 'first', stores: [{
name: 'Disney', customers: %w[
Robert Richard
]
}, {
name: 'Comix', customers: %w[
Linda Ariel
]
}]
}]
}
instance = ShoppingMall.new(hash)
instance.customers # returns %w[
# John Bobby Maria
# Danny LJ Robert Richard
# Linda Ariel
# ]
See Also:
Defined Under Namespace
Modules: Base, ClassMethods, Exception, TypeCast Classes: Config, Crawler, Fetcher, FetcherBuilder, HashReader, KeyChanger, KeyReader, MethodBuilder, Options, PostProcessor, Reader, Wrapper
Constant Summary collapse
- VERSION =
'1.6.2'