redis_props 0.0.1.alpha → 0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ test.log
2
+ .rvmrc
3
+ foobar.db
4
+ .DS_Store
5
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in redis_props.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Obie Fernandez
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,95 @@
1
+ # RedisProps
2
+
3
+ A simple way to annotate ActiveRecord objects with properties that are stored in Redis instead
4
+ of your relational database.
5
+ Perfect for adding attributes to your models that you won't have to worry about querying
6
+ or reporting on later. Examples include flags, preferences, etc.
7
+
8
+ If you provide a default value for a property definition, then RedisProps provides typecasting based on the type
9
+ inferred
10
+
11
+ Properties are lazily loaded when their accessors are invoked, but saved immediately when set. In other words,
12
+ don't rely on them to have transactional behavior along with the rest of your ActiveRecord attributes. (However, there
13
+ are plans to add a transactional modes soon.)
14
+
15
+ The current version is extracted from working code in DueProps http://dueprops.com
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ gem 'redis_props'
22
+
23
+ And then execute:
24
+
25
+ $ bundle
26
+
27
+ Or install it yourself as:
28
+
29
+ $ gem install redis_props
30
+
31
+ ## Usage
32
+
33
+ The `RedisProps` module depends on `Redis.current` (provided by the `redis` gem) being set.
34
+ Key names and namespaces are generated using a customized version of a 1-file library called `Nest`
35
+ hat we bundled into this gem.
36
+
37
+ To add RedisProps to your models just include `RedisProps` in your ActiveRecord class.
38
+
39
+ ```ruby
40
+ class Dog < ActiveRecord::Base
41
+ include RedisProps
42
+
43
+ redis_props :has_medical_condition do
44
+ define :fleas, default: false
45
+ end
46
+ end
47
+
48
+ >> dog = Dog.create(name: "Fido")
49
+ => <Dog id: 1, name: "Fido", created_at: "2012-05-13 02:15:35", updated_at: "2012-05-13 02:15:35">
50
+
51
+ >> dog.has_medical_condition_fleas?
52
+ => false
53
+
54
+ >> dog.has_medical_condition_fleas = true
55
+ => true
56
+
57
+ >> dog = Dog.find_by_name("Fido")
58
+ => <Dog id: 1, name: "Fido", created_at: "2012-05-13 02:15:35", updated_at: "2012-05-13 02:15:35">
59
+
60
+ >> dog.has_medical_condition_fleas?
61
+ => true
62
+ ```
63
+
64
+ In addition to the `define` method, you'll get a protected `r` method that returns a namespaced key that
65
+ can be used for manual redis operations.
66
+
67
+ ```ruby
68
+ >> dog = Dog.create
69
+ => <Dog id: 5, name: nil, created_at: "2012-05-13 02:15:35", updated_at: "2012-05-13 02:15:35">
70
+
71
+ >> dog.send(:r)
72
+ => "Dog:5"
73
+
74
+ >> dog.has_medical_condition_fleas = true
75
+ => true
76
+
77
+ >> dog.send(:r).redis.keys
78
+ => ["Dog:5:has_medical_condition_fleas"]
79
+ ```
80
+
81
+ ## TODOS
82
+ These are ranked in order of very likely to get done soon to less likely to get done soon (or maybe not at all.)
83
+
84
+ * Add documentation for type inference based on default values
85
+ * batch saving of attributes instead of instant
86
+ * record locking and transactions
87
+
88
+
89
+ ## Contributing
90
+
91
+ 1. Fork it
92
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
93
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
94
+ 4. Push to the branch (`git push origin my-new-feature`)
95
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/config ADDED
@@ -0,0 +1,3 @@
1
+ ---
2
+ BUNDLE_DISABLE_SHARED_GEMS: '1'
3
+ BUNDLE_PATH: vendor/bundle
data/lib/nest.rb ADDED
@@ -0,0 +1,58 @@
1
+ # Copyright (c) 2010 Michel Martens & Damian Janowski
2
+
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require "redis"
22
+
23
+ class Nest < String
24
+ VERSION = "1.1.0"
25
+
26
+ METHODS = [:append, :blpop, :brpop, :brpoplpush, :decr, :decrby,
27
+ :del, :exists, :expire, :expireat, :get, :getbit, :getrange, :getset,
28
+ :hdel, :hexists, :hget, :hgetall, :hincrby, :hkeys, :hlen, :hmget,
29
+ :hmset, :hset, :hsetnx, :hvals, :incr, :incrby, :lindex, :linsert,
30
+ :llen, :lpop, :lpush, :lpushx, :lrange, :lrem, :lset, :ltrim, :move,
31
+ :persist, :publish, :rename, :renamenx, :rpop, :rpoplpush, :rpush,
32
+ :rpushx, :sadd, :scard, :sdiff, :sdiffstore, :set, :setbit, :setex,
33
+ :setnx, :setrange, :sinter, :sinterstore, :sismember, :smembers,
34
+ :smove, :sort, :spop, :srandmember, :srem, :strlen, :subscribe,
35
+ :sunion, :sunionstore, :ttl, :type, :unsubscribe, :watch, :zadd,
36
+ :zcard, :zcount, :zincrby, :zinterstore, :zrange, :zrangebyscore,
37
+ :zrank, :zrem, :zremrangebyrank, :zremrangebyscore, :zrevrange,
38
+ :zrevrangebyscore, :zrevrank, :zscore, :zunionstore]
39
+
40
+ attr :redis
41
+
42
+ def initialize(key, redis = Redis.current)
43
+ key = key.to_redis_key if key.respond_to?(:to_redis_key)
44
+ super(key)
45
+ @redis = redis
46
+ end
47
+
48
+ def [](key)
49
+ key = key.to_redis_key if key.respond_to?(:to_redis_key)
50
+ self.class.new("#{self}:#{key}", redis)
51
+ end
52
+
53
+ METHODS.each do |meth|
54
+ define_method(meth) do |*args, &block|
55
+ redis.send(meth, self, *args, &block)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ module RedisProps
2
+ VERSION = "0.2"
3
+ end
@@ -0,0 +1,109 @@
1
+ require 'redis_props/version'
2
+ require 'nest'
3
+ require 'active_support/concern'
4
+ require 'active_record'
5
+
6
+ module RedisProps
7
+ extend ActiveSupport::Concern
8
+
9
+ def r
10
+ self.class.r[id]
11
+ end
12
+ protected :r
13
+
14
+ module ClassMethods
15
+ def r
16
+ @redis_nest ||= Nest.new(name)
17
+ end
18
+
19
+ # Specifies a set of properties to be stored in Redis
20
+ # for this ActiveRecord object instance.
21
+ #
22
+ # Options are:
23
+ # <tt>:defer</tt> - Specifies that the attributes in this context should be flushed
24
+ # to Redis only when the ActiveRecord object is saved. This option defaults to +false+
25
+ # and the default behavior is to read and write values to/from Redis immediately as
26
+ # they are accessed.
27
+ #
28
+ # <tt>:touch</tt> - Specifies that this ActiveRecord object's +updated_at+ field should
29
+ # be updated on save (aka "touching the object") when you write new attributes values,
30
+ # even if no database-backed attributes were changed. This option is occasionally
31
+ # vital when dealing with cache invalidation in Rails. If you specify
32
+ # a symbol (vs :true), then that attribute will be updated with the current
33
+ # time instead of the updated_at/on attribute.
34
+ # This option defaults to +false+.
35
+ #
36
+ def props(context_name, opts={}, &block)
37
+ PropsContext.new(context_name, self, opts, block)
38
+ end
39
+ end
40
+
41
+ class PropsContext
42
+ def initialize(context_name, klass, opts, block)
43
+ @context_name, @klass, @opts = context_name, klass, opts
44
+ instance_exec(&block)
45
+ end
46
+
47
+ def define(name, d_opts={})
48
+ add_methods_to(@klass, "#{@context_name}_#{name}", d_opts, @opts)
49
+ end
50
+
51
+ private
52
+
53
+ def add_methods_to(klass, d_name, d_opts, ctx_opts)
54
+ klass.class_eval do
55
+ define_method("#{d_name}") do
56
+ instance_variable_get("@#{d_name}") || begin
57
+ val = r[d_name].get
58
+ val = val.nil? ? d_opts[:default] : PropsContext.typecaster(d_opts[:default]).call(val)
59
+ instance_variable_set("@#{d_name}", val)
60
+ end
61
+ end
62
+ define_method("#{d_name}?") do
63
+ !!send(d_name)
64
+ end
65
+ define_method("#{d_name}=") do |val|
66
+ instance_variable_set("@#{d_name}", val)
67
+ r[d_name].set val.to_s
68
+ if touch = ctx_opts[:touch]
69
+ if touch == true
70
+ if respond_to?(:updated_at)
71
+ self.updated_at = Time.now
72
+ elsif respond_to?(:updated_on)
73
+ self.updated_at = Time.now
74
+ else
75
+ raise "updated timestamp column does not exist for use with the :touch option"
76
+ end
77
+ elsif respond_to? touch
78
+ send("#{touch}=", Time.now)
79
+ else
80
+ raise "#{touch} timestamp column specified as :touch option does not exist"
81
+ end
82
+ end
83
+ end
84
+ after_destroy -> { r[d_name].del }
85
+ end
86
+ end
87
+
88
+ def self.typecaster(default_value)
89
+ case default_value
90
+ when TrueClass, FalseClass
91
+ @boolean ||= lambda {|v| ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES.include?(v)}
92
+ when Float
93
+ @float ||= lambda {|v| v.to_f }
94
+ when BigDecimal
95
+ @decimal ||= lambda {|v| v.to_d }
96
+ when Integer
97
+ @integer ||= lambda {|v| v.to_i }
98
+ when Range
99
+ @range ||= lambda {|v| eval(v) }
100
+ when Date
101
+ @date ||= lambda {|v| ActiveRecord::ConnectionAdapters::Column.send(:string_to_date, v) }
102
+ when Time
103
+ @time ||= lambda {|v| ActiveRecord::ConnectionAdapters::Column.send(:string_to_time, v) }
104
+ else
105
+ lambda {|v| v}
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/redis_props/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "redis_props"
6
+ gem.version = RedisProps::VERSION
7
+ gem.authors = ["Obie Fernandez"]
8
+ gem.email = ["obiefernandez@gmail.com"]
9
+ gem.description = %q{A simple way to annotate ActiveRecord objects with properties that are stored in Redis.
10
+ Perfect for adding attributes to your models that you won't have to worry about querying
11
+ or reporting on later. Examples include flags, preferences, etc.}
12
+ gem.summary = %q{Add non-relational attributes to your ActiveRecord objects.}
13
+ gem.homepage = "http://github.com/obie/redis_properties"
14
+
15
+ gem.files = `git ls-files`.split($\)
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_development_dependency "rspec"
21
+ gem.add_development_dependency "activesupport"
22
+ gem.add_development_dependency "sqlite3"
23
+ gem.add_development_dependency "pry-nav"
24
+
25
+ gem.add_runtime_dependency "activesupport"
26
+ gem.add_runtime_dependency "activerecord"
27
+ gem.add_runtime_dependency "redis"
28
+ end
@@ -0,0 +1,147 @@
1
+ require 'spec_helper'
2
+ require 'sqlite3'
3
+ require 'active_record'
4
+
5
+ class Dog < ActiveRecord::Base
6
+ include RedisProps
7
+
8
+ establish_connection :adapter => 'sqlite3', :database => 'spec/foobar.db'
9
+ connection.create_table :dogs, :force => true do |t|
10
+ t.string :name
11
+ t.timestamps
12
+ end
13
+
14
+ props :has_medical_condition do
15
+ define :fleas, default: false
16
+ define :pants, default: true
17
+ end
18
+
19
+ props :appearance, touch: true do
20
+ define :coat
21
+ end
22
+ end
23
+
24
+ class User < ActiveRecord::Base
25
+ include RedisProps
26
+
27
+ establish_connection :adapter => 'sqlite3', :database => 'spec/foobar.db'
28
+ connection.create_table :users, :force => true do |t|
29
+ t.string :name
30
+ t.timestamp :saved_at
31
+ end
32
+
33
+ props :flags, touch: :saved_at do
34
+ define :weekly_digest, default: true
35
+ end
36
+
37
+ props :number_of do
38
+ define :records, default: 0
39
+ end
40
+
41
+ props :pets do
42
+ define :dogs, default: []
43
+ end
44
+
45
+ props :stats do
46
+ define :birthday, default: 20.years.ago
47
+ define :temperature, default: 98.7
48
+ define :last_seen, default: Date.today
49
+ define :pressure_range, default: 70..99
50
+ define :exact_weight, default: "190.908230984".to_d
51
+ end
52
+ end
53
+
54
+ describe RedisProps do
55
+ let(:clean_dog) { Dog.create!(name: "Wego") }
56
+ let(:dirty_dog) { Dog.create!(name: "Bodiddly") }
57
+ let(:user) { User.create!(name: "Hugo", saved_at: 1.day.ago) }
58
+
59
+ context "props options" do
60
+ it "should touch the AR object's updated_at if touch: true" do
61
+ orig_updated_at = clean_dog.updated_at
62
+ clean_dog.appearance_coat = "Scruffy"
63
+ clean_dog.save
64
+ Dog.find_by_name("Wego").updated_at.should_not == orig_updated_at
65
+ end
66
+ it "should touch the AR object's saved_at if touch: :saved_at" do
67
+ orig_saved_at = user.saved_at
68
+ user.flags_weekly_digest = false
69
+ user.save
70
+ User.find_by_name("Hugo").saved_at.should_not == orig_saved_at
71
+ end
72
+ end
73
+
74
+ context "props definitions" do
75
+ it "creates persistent attributes" do
76
+ dirty_dog.has_medical_condition_fleas = true
77
+ dirty_dog = Dog.find_by_name "Bodiddly"
78
+ dirty_dog.should have_medical_condition_fleas
79
+ end
80
+
81
+ it "sets defaults if provided" do
82
+ clean_dog.should have_medical_condition_pants
83
+ clean_dog.should_not have_medical_condition_fleas
84
+ end
85
+
86
+ context "provide type inference based on default values provided" do
87
+ it "works for booleans of all kinds" do
88
+ user.flags_weekly_digest = false
89
+ User.find(user.id).flags_weekly_digest.should == false
90
+ user.flags_weekly_digest = true
91
+ User.find(user.id).flags_weekly_digest.should == true
92
+ user.flags_weekly_digest = 1
93
+ User.find(user.id).flags_weekly_digest.should == true
94
+ user.flags_weekly_digest = 0
95
+ User.find(user.id).flags_weekly_digest.should == false
96
+ user.flags_weekly_digest = 't'
97
+ User.find(user.id).flags_weekly_digest.should == true
98
+ user.flags_weekly_digest = 'f'
99
+ User.find(user.id).flags_weekly_digest.should == false
100
+ end
101
+ it "works for integers" do
102
+ user.number_of_records = 42
103
+ User.find(user.id).number_of_records.should == 42
104
+ end
105
+ it "works for floats" do
106
+ user.stats_temperature = 99.9
107
+ User.find(user.id).stats_temperature.should == 99.9
108
+ end
109
+ it "works for times" do
110
+ new_birthday = 10.years.ago
111
+ user.stats_birthday = new_birthday
112
+ # todo: figure out why straight comparison is failing
113
+ User.find(user.id).stats_birthday.to_i.should == new_birthday.to_i
114
+ end
115
+ it "works for dates" do
116
+ new_last_seen = 10.days.ago.to_date
117
+ user.stats_last_seen = new_last_seen
118
+ User.find(user.id).stats_last_seen.should == new_last_seen
119
+ end
120
+ it "works for ranges" do
121
+ new_range = 90..114
122
+ user.stats_pressure_range = new_range
123
+ User.find(user.id).stats_pressure_range.should == new_range
124
+ end
125
+ it "works for decimals" do
126
+ user.stats_exact_weight = "230.29320".to_d
127
+ User.find(user.id).stats_exact_weight.should == "230.29320".to_d
128
+ end
129
+ it "works for relationships stored in arrays" do
130
+ user.pets_dogs << clean_dog
131
+ User.find(user.id).pets_dogs.should include(clean_dog)
132
+ end
133
+ end
134
+ end
135
+
136
+ context "default behavior" do
137
+ it "is to remove associated redis keys when parent AR object is destroyed" do
138
+ user.class_eval { public :r }
139
+ user.flags_weekly_digest = false
140
+ user.r["flags_weekly_digest"].get.should == "false"
141
+ user.destroy
142
+ user.r["flags_weekly_digest"].get.should == nil
143
+ end
144
+ end
145
+ end
146
+
147
+
@@ -0,0 +1,19 @@
1
+ require 'logger'
2
+ require 'pry'
3
+ require 'redis_props'
4
+
5
+ module RedisProps
6
+ class Rails
7
+ def self.env
8
+ "test"
9
+ end
10
+ end
11
+ end
12
+
13
+ Redis.current = Redis.new(db: 13)
14
+
15
+ RSpec.configure do |c|
16
+ c.before(:each) { Redis.current.flushdb }
17
+ end
18
+
19
+ ActiveRecord::Base.logger = Logger.new("test.log")
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis_props
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.alpha
5
- prerelease: 6
4
+ version: '0.2'
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Obie Fernandez
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-18 00:00:00.000000000 Z
12
+ date: 2012-05-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &2151840620 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2151840620
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: activesupport
27
- requirement: &2151837620 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,21 +37,15 @@ dependencies:
32
37
  version: '0'
33
38
  type: :development
34
39
  prerelease: false
35
- version_requirements: *2151837620
36
- - !ruby/object:Gem::Dependency
37
- name: sqlite3
38
- requirement: &2151836040 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
39
41
  none: false
40
42
  requirements:
41
43
  - - ! '>='
42
44
  - !ruby/object:Gem::Version
43
45
  version: '0'
44
- type: :development
45
- prerelease: false
46
- version_requirements: *2151836040
47
46
  - !ruby/object:Gem::Dependency
48
- name: activerecord
49
- requirement: &2151833240 !ruby/object:Gem::Requirement
47
+ name: sqlite3
48
+ requirement: !ruby/object:Gem::Requirement
50
49
  none: false
51
50
  requirements:
52
51
  - - ! '>='
@@ -54,21 +53,15 @@ dependencies:
54
53
  version: '0'
55
54
  type: :development
56
55
  prerelease: false
57
- version_requirements: *2151833240
58
- - !ruby/object:Gem::Dependency
59
- name: redis-namespace
60
- requirement: &2151831420 !ruby/object:Gem::Requirement
56
+ version_requirements: !ruby/object:Gem::Requirement
61
57
  none: false
62
58
  requirements:
63
59
  - - ! '>='
64
60
  - !ruby/object:Gem::Version
65
61
  version: '0'
66
- type: :development
67
- prerelease: false
68
- version_requirements: *2151831420
69
62
  - !ruby/object:Gem::Dependency
70
63
  name: pry-nav
71
- requirement: &2151829760 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
72
65
  none: false
73
66
  requirements:
74
67
  - - ! '>='
@@ -76,10 +69,15 @@ dependencies:
76
69
  version: '0'
77
70
  type: :development
78
71
  prerelease: false
79
- version_requirements: *2151829760
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
80
78
  - !ruby/object:Gem::Dependency
81
79
  name: activesupport
82
- requirement: &2151828460 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
83
81
  none: false
84
82
  requirements:
85
83
  - - ! '>='
@@ -87,10 +85,15 @@ dependencies:
87
85
  version: '0'
88
86
  type: :runtime
89
87
  prerelease: false
90
- version_requirements: *2151828460
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
91
94
  - !ruby/object:Gem::Dependency
92
95
  name: activerecord
93
- requirement: &2151826880 !ruby/object:Gem::Requirement
96
+ requirement: !ruby/object:Gem::Requirement
94
97
  none: false
95
98
  requirements:
96
99
  - - ! '>='
@@ -98,10 +101,15 @@ dependencies:
98
101
  version: '0'
99
102
  type: :runtime
100
103
  prerelease: false
101
- version_requirements: *2151826880
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
102
110
  - !ruby/object:Gem::Dependency
103
111
  name: redis
104
- requirement: &2151825960 !ruby/object:Gem::Requirement
112
+ requirement: !ruby/object:Gem::Requirement
105
113
  none: false
106
114
  requirements:
107
115
  - - ! '>='
@@ -109,18 +117,12 @@ dependencies:
109
117
  version: '0'
110
118
  type: :runtime
111
119
  prerelease: false
112
- version_requirements: *2151825960
113
- - !ruby/object:Gem::Dependency
114
- name: redis-namespace
115
- requirement: &2151824960 !ruby/object:Gem::Requirement
120
+ version_requirements: !ruby/object:Gem::Requirement
116
121
  none: false
117
122
  requirements:
118
123
  - - ! '>='
119
124
  - !ruby/object:Gem::Version
120
125
  version: '0'
121
- type: :runtime
122
- prerelease: false
123
- version_requirements: *2151824960
124
126
  description: ! "A simple way to annotate ActiveRecord objects with properties that
125
127
  are stored in Redis.\n Perfect for adding attributes to
126
128
  your models that you won't have to worry about querying\n or
@@ -130,7 +132,19 @@ email:
130
132
  executables: []
131
133
  extensions: []
132
134
  extra_rdoc_files: []
133
- files: []
135
+ files:
136
+ - .gitignore
137
+ - Gemfile
138
+ - LICENSE
139
+ - README.md
140
+ - Rakefile
141
+ - config
142
+ - lib/nest.rb
143
+ - lib/redis_props.rb
144
+ - lib/redis_props/version.rb
145
+ - redis_props.gemspec
146
+ - spec/redis_props/redis_props_spec.rb
147
+ - spec/spec_helper.rb
134
148
  homepage: http://github.com/obie/redis_properties
135
149
  licenses: []
136
150
  post_install_message:
@@ -146,13 +160,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
146
160
  required_rubygems_version: !ruby/object:Gem::Requirement
147
161
  none: false
148
162
  requirements:
149
- - - ! '>'
163
+ - - ! '>='
150
164
  - !ruby/object:Gem::Version
151
- version: 1.3.1
165
+ version: '0'
152
166
  requirements: []
153
167
  rubyforge_project:
154
- rubygems_version: 1.8.10
168
+ rubygems_version: 1.8.22
155
169
  signing_key:
156
170
  specification_version: 3
157
171
  summary: Add non-relational attributes to your ActiveRecord objects.
158
- test_files: []
172
+ test_files:
173
+ - spec/redis_props/redis_props_spec.rb
174
+ - spec/spec_helper.rb