Skip to content

Instantly share code, notes, and snippets.

@budu
Created November 14, 2013 02:41
Show Gist options
  • Save budu/7460434 to your computer and use it in GitHub Desktop.
Save budu/7460434 to your computer and use it in GitHub Desktop.
Prototype of a new DSL to consume json API
module Bacon
class Resource
def initialize(name, parent, options = {})
@name = name
@parent = parent
@options = options
@result = options[:result] || []
end
def call(method, *args)
if @options[:debug]
puts "#{method}: #{root_path}#{path(*args)}"
else
# TODO: send data as json
JSON.parse Faraday.new(url: @options[:url])
.send(method, "#{root_path}#{path(*args)}")
.body
end
end
def chain
self.chain!
self
end
def chain!
@options[:chain] = true
end
def <<(record)
arg = record.try("#{@name.to_s.singularize}_id")
method = arg ? :put : :post
call method, arg
end
def args
@options[:args]
end
def cache
$bacon_resource_cache ||=
ActiveSupport::Cache::MemoryStore.new expires_in: 10.minutes
end
def load(force = false)
@result = if @options[:chain] && !force
nil
elsif @options[:stub]
@options[:stub]
elsif @options[:debug]
call :get
else
cache.fetch(path) { call :get }
end
Bacon::Resource.new @name, @parent, @options.merge(result: @result)
end
def parent
@parent
end
def path(*extra_args)
[ parent.try(:path),
@name,
*((args || []).map do |arg|
case arg
when ActiveRecord::Base then arg.id
else arg.to_s
end
end),
*extra_args
].compact.join '/'
end
def root_path
@options[:root_path] || '/'
end
def method_missing(symbol, *args, &block)
load
if @result.respond_to? symbol
@result.send symbol, *args, &block
else
Bacon::Resource.new symbol, self, @options
.except(:args, :stub, :result)
.merge(args: args,
block: block,
chain: true)
end
end
def respond_to?(symbol, include_all = false)
super || @result.respond_to?(symbol, include_all)
end
def to_a
load
@result
end
def value
load true
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment