Created
March 16, 2012 20:30
-
-
Save jmervine/2052468 to your computer and use it in GitHub Desktop.
Rails: Dynamic Model from JSON sans DB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'net/http' | |
class Item | |
#replaced with dynamic initialization below | |
#attr_reader :id, :user, :state | |
# | |
# | |
# Sample JSON | |
# | |
# [{ "id":1, "user":"john", "state":"active" }, | |
# { "id":2, "user":"jane", "state":"inactive" }, | |
# { "id":3, "user":"jack", "state":"active" }, | |
# { "id":4, "user":"jeff", "state":"inactive" }, | |
# { "id":5, "user":"jimm", "state":"active" }] | |
# | |
# | |
# Adding JSON class variable and setter to make this even more dynamic. | |
# note: I'm sure there's a better way to do this... | |
# e.g. with a configure block or something. | |
# | |
# Additionally, adding auto ssl stuff... | |
@@json_path = nil | |
@@use_ssl = false | |
def self.json_path=(path) | |
@@use_ssl = true if path =~ /^https/ | |
@@json_path = path | |
end | |
# To use the above, add: | |
# Item.json_path = "<path>" | |
# to your config/environment.rb or | |
# config/environments/*.rb | |
# | |
# This will pre-load it in to your application. | |
# | |
def self.all | |
self.get_items_from_source.map { |i| new(i) } | |
end | |
def self.find( param ) | |
all.detect { |i| i.id == param } || raise(ActiveRecord::RecordNotFound) | |
end | |
def self.where( query ) | |
ret = [] | |
all.each { |i| ret.push(i) if i.include?(query) } || | |
raise(ActiveRecord::RecordNotFound) | |
return ret | |
end | |
def initialize item | |
raise "expected Hash param" unless item.kind_of? Hash | |
item.each do |key,value| | |
instance_variable_set("@#{key.to_s}".to_sym, value) | |
define_singleton_method(key.to_s) { instance_variable_get("@#{key.to_s}".to_sym) } | |
end | |
end | |
# replaced with dynamic initialization above | |
#def initialize hash | |
#@id = hash["id"] | |
#@user = hash["user"] | |
#@state = hash["state"] | |
#end | |
def include? query | |
raise InvalidParamType | |
unless query.respond_to?('has_key?') and query.respond_to?('has_value?') | |
query.each do |k,v| | |
return false unless self.instance_variable_get("@#{k.to_s}".to_sym) == v | |
end | |
end | |
protected | |
def self.get_items_from_source | |
raise MissingJsonPath if @@json_path.nil? | |
items = [] | |
uri = URI.parse(@@json_path) | |
if @@use_ssl | |
require 'openssl' | |
http = Net::HTTP.new(uri.host, uri.port) | |
http.use_ssl = true | |
request = Net::HTTP::Get.new(uri.request_uri) | |
response = http.request(request) | |
else | |
response = Net::HTTP.get_response(uri) | |
end | |
JSON.parse(response.body).each { |i| items.push i } | |
items | |
end | |
# custom exceptions | |
class InvalidParamType < Exception | |
end | |
class MissingJsonPath < Exception | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Rails requires JSON by default. This works perfectly without Rails, except you have to require 'json' before using.