Jump to content

The ultimate community for Ruby on Rails developers.


Photo

JSON as data source!?


  • Please log in to reply
2 replies to this topic

#1 ChrisH

ChrisH

    Passenger

  • Members
  • 3 posts

Posted 08 May 2014 - 12:52 PM

Hi!

 

I'm pretty new to rails & ruby, but I think I'm doiung well! ;?)

 

I have a json file with "a lot" of data (well 156KB / 251 entries) that I want to access from within my rails app, and I'm not sure on what the best way would be.

 

I need be able to "find" one specific entry (based on one of two different attributes/indices), and even if there's times when I need to output "column A and B from all entries", the rest of the data is unnecessary at that specific moment (I don't even need all of the "columns").. 

 

What is the best way?

 

Should I import the file to memory at "boot" (is there a ActiveRecord for JSON?).

Should I try to add it to the seeding and store it in a table in the DB.



#2 Ohm

Ohm

    Driver

  • Moderators
  • 398 posts
  • LocationCopenhagen

Posted 08 May 2014 - 10:12 PM   Best Answer

Here's what I'd do. Keep in mind that it might not be the best solution.

 

I'd load the data into memory on boot, because, lets face it, 251 entries isn't really that much data.

I'd then parse the JSON to a Ruby hash and then just access it as a hash.

 

If you want to get really fancy, you could write up a wrapper for it, so that you'd get ActiveRecord like access sorta like

class JSONHash
  attr_accessor :hash
  
  def initialize(hash = {})
    @hash = hash
  end
    
  def get(fields = [])
    @hash.select { |k, _| fields.include?(k) }
  end
end    

  • ChrisH likes this
Blog: http://ohm.sh | Twitter: @madsohm

#3 ChrisH

ChrisH

    Passenger

  • Members
  • 3 posts

Posted 09 May 2014 - 10:23 AM

Thank you!

 

I ended up writing a class that sort of imitates ActiveRecord (it might not be the best [or most beautiful] way, nut it works ;?D )


class Country
  cattr_accessor :countries
  
  def self.set_data(hash = {})
    @@countries = hash
  end
    
  def self.get(id)
    return_obj @@countries.find { |v, _| v['cca2'] == id.upcase }
  end
  
  def self.find_by_name(name)
    return_obj @@countries.find { |v, _| v['name'].casecmp(name).zero? }
  end
  
  def self.find_by_callingcode(cc)
    return_obj @@countries.find { |v, _| v['callingCode'].include? cc.to_s }
  end
  
  def self.find_by_tld(tld)
    tld.prepend('.') unless tld.starts_with?('.')
    return_obj @@countries.find { |v, _| v['tld'].include? tld.downcase }
  end
  
  def self.find_by_currency(currency)
    return_obj @@countries.find { |v, _| v['currency'].include? currency.upcase }
  end
  
  def self.find_by_languagecode(lang)
    return_obj @@countries.find { |v, _| v['languageCodes'].include? lang.downcase }
  end
  
  def self.find_by_region(region)
    @@countries.select { |v, _| v['region'].casecmp(region).zero? }.map { |r| return_obj r }
  end
  
  def self.find_by_subregion(region)  
    @@countries.select { |v, _| v['subregion'].casecmp(region).zero? }.map { |r| return_obj r }
  end
  
  def self.find_by(fields = {})
    key, val = fields.first
    return_obj @@countries.find { |v, _| v[key.to_s].casecmp(val).zero? unless v[key.to_s].nil? }
  end
 
  def self.find_all_by(fields = {})
    k, val = fields.first
    key = k.to_s
    list = @@countries.select do
      |v, _|
      if v[key].kind_of?(Array)
        v[key].include? val
      elsif ! v[key].nil?
        v[key].casecmp(val).zero?
      end
    end
    list.map { |r| return_obj r } unless list.nil?
  end
  
  class << self
    alias :find :get
    alias :find_by_cca2 :get
    alias :find_by_countrycode :get
  end
  
  private
    def self.return_obj(data)
      OpenStruct.new data
    end
end





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users