Skip to content

Instantly share code, notes, and snippets.

@seapy
Created August 24, 2014 08:04
Show Gist options
  • Select an option

  • Save seapy/1b129c9aa140f16803ce to your computer and use it in GitHub Desktop.

Select an option

Save seapy/1b129c9aa140f16803ce to your computer and use it in GitHub Desktop.

Revisions

  1. @jimeh jimeh revised this gist Apr 3, 2010. 1 changed file with 8 additions and 7 deletions.
    15 changes: 8 additions & 7 deletions setting.rb
    Original file line number Diff line number Diff line change
    @@ -22,17 +22,18 @@ def self.method_missing(method, *args)
    # key/value setup
    method = method.chop
    method = method.chop if method[-1,1] == "!"
    @__cache.write(method, args[0], :expires_in => @__cache_expires_in)
    value = {:value => args[0]}
    @__cache.write(method, value, :expires_in => @__cache_expires_in)
    setting = self.find(:first, :conditions => {:key => method})
    if args[0].nil?
    if value[:value].nil?
    setting.destroy if setting
    @__cache.write(method, nil, :expires_in => 0.seconds)
    else
    setting = self.new if !setting
    setting.key = method.to_s if setting.key.blank?
    setting.value = args[0]
    setting.value = value
    if setting.save
    return args[0]
    return value[:value]
    end
    end
    end
    @@ -47,12 +48,12 @@ def self.method_missing(method, *args)
    end

    if skip_cache.nil? && (result = @__cache.read(method.to_s))
    return result
    return result[:value]
    else
    result = self.find(:first, :conditions => {:key => method})
    if result
    @__cache.write(method, result.value, :expires_in => @__cache_expires_in)
    return result.value
    return result.value[:value]
    end
    end

    @@ -61,4 +62,4 @@ def self.method_missing(method, *args)

    end

    end
    end
  2. @jimeh jimeh revised this gist Feb 8, 2010. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion setting.rb
    Original file line number Diff line number Diff line change
    @@ -23,8 +23,8 @@ def self.method_missing(method, *args)
    method = method.chop
    method = method.chop if method[-1,1] == "!"
    @__cache.write(method, args[0], :expires_in => @__cache_expires_in)
    setting = self.find(:first, :conditions => {:key => method})
    if args[0].nil?
    setting = self.find(:first, :conditions => {:key => method})
    setting.destroy if setting
    @__cache.write(method, nil, :expires_in => 0.seconds)
    else
  3. @jimeh jimeh revised this gist Feb 1, 2010. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions setting.rb
    Original file line number Diff line number Diff line change
    @@ -20,8 +20,8 @@ def self.method_missing(method, *args)

    if args.size > 0
    # key/value setup
    method = method[0,method.length-1]
    method = method[0,method.length-1] if method[-1,1] == "!"
    method = method.chop
    method = method.chop if method[-1,1] == "!"
    @__cache.write(method, args[0], :expires_in => @__cache_expires_in)
    if args[0].nil?
    setting = self.find(:first, :conditions => {:key => method})
    @@ -42,7 +42,7 @@ def self.method_missing(method, *args)

    # skip memcache?
    if method[-1,1] == "!"
    method = method[0,method.length-1]
    method = method.chop
    skip_cache = true
    end

  4. @jimeh jimeh revised this gist Feb 1, 2010. 1 changed file with 23 additions and 20 deletions.
    43 changes: 23 additions & 20 deletions setting.rb
    Original file line number Diff line number Diff line change
    @@ -15,8 +15,30 @@ def self.method_missing(method, *args)

    method = method.to_s

    # set mode
    if method[-1,1] == "="

    if args.size > 0
    # key/value setup
    method = method[0,method.length-1]
    method = method[0,method.length-1] if method[-1,1] == "!"
    @__cache.write(method, args[0], :expires_in => @__cache_expires_in)
    if args[0].nil?
    setting = self.find(:first, :conditions => {:key => method})
    setting.destroy if setting
    @__cache.write(method, nil, :expires_in => 0.seconds)
    else
    setting = self.new if !setting
    setting.key = method.to_s if setting.key.blank?
    setting.value = args[0]
    if setting.save
    return args[0]
    end
    end
    end

    # get mode
    if method[-1,1] != "="
    else

    # skip memcache?
    if method[-1,1] == "!"
    @@ -34,25 +56,6 @@ def self.method_missing(method, *args)
    end
    end

    # set mode
    elsif args.size > 0
    # key/value setup
    method = method[0,method.length-1]
    method = method[0,method.length-1] if method[-1,1] == "!"
    @__cache.write(method, args[0], :expires_in => @__cache_expires_in)
    setting = self.find(:first, :conditions => {:key => method})
    if args[0].nil? && setting
    setting.destroy
    @__cache.write(method, nil, :expires_in => 0.seconds)
    else
    setting = self.new if !setting
    setting.key = method.to_s if setting.key.blank?
    setting.value = args[0]
    if setting.save
    return args[0]
    end
    end

    end
    return nil

  5. @jimeh jimeh revised this gist Jan 17, 2010. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion setting.rb
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@ class Setting < ActiveRecord::Base

    class << self
    attr_accessor :__cache
    attr_accessor :__cache_expire_in
    attr_accessor :__cache_expires_in
    end

    def self.method_missing(method, *args)
  6. @jimeh jimeh revised this gist Jan 17, 2010. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -17,7 +17,7 @@ The settings table has two columns, a `key` and a `value` column. The `value` co
    => nil

    # setting a value, writes it to memcache, and saves or updates a database
    # record is the form of {:name => "hello", :value => serialize(["world"])}
    # record is the form of {:key => "hello", :value => serialize(["world"])}
    >> Setting.hello = ["world"]
    => ["hello"]

  7. @jimeh jimeh revised this gist Jan 17, 2010. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -16,7 +16,7 @@ The settings table has two columns, a `key` and a `value` column. The `value` co
    >> Setting.hello
    => nil

    # setting a value, saves it to memcache, and saves a database
    # setting a value, writes it to memcache, and saves or updates a database
    # record is the form of {:name => "hello", :value => serialize(["world"])}
    >> Setting.hello = ["world"]
    => ["hello"]
  8. @jimeh jimeh revised this gist Jan 17, 2010. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -15,19 +15,24 @@ The settings table has two columns, a `key` and a `value` column. The `value` co
    # fetching a value
    >> Setting.hello
    => nil

    # setting a value, saves it to memcache, and saves a database
    # record is the form of {:name => "hello", :value => serialize(["world"])}
    >> Setting.hello = ["world"]
    => ["hello"]

    # fetching the value again, which will only read from memcache
    >> Setting.hello
    => ["hello"]

    # force fetch from database and update memcache
    >> Setting.hello!
    => ["hello"]

    # remove the hello key from memcache and the database
    >> Setting.hello = nil
    => nil

    # default memcache expire_in option is 6.hours, you can change it...
    >> Setting.__cache_expires_in = 1.hour
    => 3600 seconds
  9. @jimeh jimeh revised this gist Jan 17, 2010. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,8 @@ The settings table has two columns, a `key` and a `value` column. The `value` co
    # fetching a value
    >> Setting.hello
    => nil
    # setting a value, saves it to memcache, and saves a database record is the form of {:name => "hello", :value => serialize(["world"])}
    # setting a value, saves it to memcache, and saves a database
    # record is the form of {:name => "hello", :value => serialize(["world"])}
    >> Setting.hello = ["world"]
    => ["hello"]
    # fetching the value again, which will only read from memcache
  10. @jimeh jimeh revised this gist Jan 17, 2010. 3 changed files with 13 additions and 6 deletions.
    3 changes: 3 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -27,4 +27,7 @@ The settings table has two columns, a `key` and a `value` column. The `value` co
    # remove the hello key from memcache and the database
    >> Setting.hello = nil
    => nil
    # default memcache expire_in option is 6.hours, you can change it...
    >> Setting.__cache_expires_in = 1.hour
    => 3600 seconds

    File renamed without changes.
    16 changes: 10 additions & 6 deletions app/model/setting.rb → setting.rb
    Original file line number Diff line number Diff line change
    @@ -3,12 +3,15 @@ class Setting < ActiveRecord::Base
    serialize :value

    class << self
    attr_accessor :_mcache
    attr_accessor :__cache
    attr_accessor :__cache_expire_in
    end

    def self.method_missing(method, *args)

    # init memcache if needed
    @_mcache = ActiveSupport::Cache::MemCacheStore.new if @_mcache.nil?
    @__cache = ActiveSupport::Cache::MemCacheStore.new if @__cache.nil?
    @__cache_expires_in = 6.hours if @__cache_expires_in.nil?

    method = method.to_s

    @@ -21,25 +24,26 @@ def self.method_missing(method, *args)
    skip_cache = true
    end

    if skip_cache.nil? && (result = @_mcache.read(method.to_s))
    if skip_cache.nil? && (result = @__cache.read(method.to_s))
    return result
    else
    result = self.find(:first, :conditions => {:key => method})
    if result
    @_mcache.write(method, result.value, :expires_in => 6.hours)
    @__cache.write(method, result.value, :expires_in => @__cache_expires_in)
    return result.value
    end
    end

    # set mode
    elsif args.size > 0
    # key/value setup
    method = method[0,method.length-1]
    method = method[0,method.length-1] if method[-1,1] == "!"
    @_mcache.write(method, args[0], :expires_in => 6.hours)
    @__cache.write(method, args[0], :expires_in => @__cache_expires_in)
    setting = self.find(:first, :conditions => {:key => method})
    if args[0].nil? && setting
    setting.destroy
    @_mcache.write(method, nil, :expires_in => 0.seconds)
    @__cache.write(method, nil, :expires_in => 0.seconds)
    else
    setting = self.new if !setting
    setting.key = method.to_s if setting.key.blank?
  11. @jimeh jimeh created this gist Jan 17, 2010.
    30 changes: 30 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,30 @@
    # Rails Setting model

    This is a semi-quick key/value store I put together for a quick way to store temporary data related to what's in my database, in a reliable way. For example, I'm using it to keep track of where a hourly and a daily crontask that processes statistics left off, so it can resume only processing and summarizing new data on the next run.

    Code quality most likely is not great, but it works. And I will update this gist as I update my project.


    ## How It Works

    The settings table has two columns, a `key` and a `value` column. The `value` column is serialized, so you can technically store almost anything in there. Memcache is also used as a caching layer to minimize database calls.


    ## Example usage

    # fetching a value
    >> Setting.hello
    => nil
    # setting a value, saves it to memcache, and saves a database record is the form of {:name => "hello", :value => serialize(["world"])}
    >> Setting.hello = ["world"]
    => ["hello"]
    # fetching the value again, which will only read from memcache
    >> Setting.hello
    => ["hello"]
    # force fetch from database and update memcache
    >> Setting.hello!
    => ["hello"]
    # remove the hello key from memcache and the database
    >> Setting.hello = nil
    => nil

    57 changes: 57 additions & 0 deletions app/model/setting.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,57 @@
    class Setting < ActiveRecord::Base

    serialize :value

    class << self
    attr_accessor :_mcache
    end

    def self.method_missing(method, *args)
    # init memcache if needed
    @_mcache = ActiveSupport::Cache::MemCacheStore.new if @_mcache.nil?

    method = method.to_s

    # get mode
    if method[-1,1] != "="

    # skip memcache?
    if method[-1,1] == "!"
    method = method[0,method.length-1]
    skip_cache = true
    end

    if skip_cache.nil? && (result = @_mcache.read(method.to_s))
    return result
    else
    result = self.find(:first, :conditions => {:key => method})
    if result
    @_mcache.write(method, result.value, :expires_in => 6.hours)
    return result.value
    end
    end

    # set mode
    elsif args.size > 0
    method = method[0,method.length-1]
    method = method[0,method.length-1] if method[-1,1] == "!"
    @_mcache.write(method, args[0], :expires_in => 6.hours)
    setting = self.find(:first, :conditions => {:key => method})
    if args[0].nil? && setting
    setting.destroy
    @_mcache.write(method, nil, :expires_in => 0.seconds)
    else
    setting = self.new if !setting
    setting.key = method.to_s if setting.key.blank?
    setting.value = args[0]
    if setting.save
    return args[0]
    end
    end

    end
    return nil

    end

    end
    14 changes: 14 additions & 0 deletions db/migrate/create_settings.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,14 @@
    class CreateSettings < ActiveRecord::Migration
    def self.up
    create_table :settings, :options => "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.string :key
    t.text :value
    end

    add_index :settings, :key, :unique => true
    end

    def self.down
    drop_table :settings
    end
    end