hstore_flags 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.gem
2
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source :rubygems
2
+ gemspec
3
+
4
+ gem 'activerecord', '~>3.0'
5
+ gem 'activerecord-postgres-hstore', '~>0.4'
6
+ gem 'pg', '~>0.14'
7
+ gem 'rspec', '~>2'
8
+ gem 'rake'
data/Gemfile.lock ADDED
@@ -0,0 +1,111 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ hstore_flags (0.0.3)
5
+ activerecord (~> 3.0)
6
+ activerecord-postgres-hstore (~> 0.4)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ actionmailer (3.2.8)
12
+ actionpack (= 3.2.8)
13
+ mail (~> 2.4.4)
14
+ actionpack (3.2.8)
15
+ activemodel (= 3.2.8)
16
+ activesupport (= 3.2.8)
17
+ builder (~> 3.0.0)
18
+ erubis (~> 2.7.0)
19
+ journey (~> 1.0.4)
20
+ rack (~> 1.4.0)
21
+ rack-cache (~> 1.2)
22
+ rack-test (~> 0.6.1)
23
+ sprockets (~> 2.1.3)
24
+ activemodel (3.2.8)
25
+ activesupport (= 3.2.8)
26
+ builder (~> 3.0.0)
27
+ activerecord (3.2.8)
28
+ activemodel (= 3.2.8)
29
+ activesupport (= 3.2.8)
30
+ arel (~> 3.0.2)
31
+ tzinfo (~> 0.3.29)
32
+ activerecord-postgres-hstore (0.4.1)
33
+ pg
34
+ rails
35
+ rake
36
+ activeresource (3.2.8)
37
+ activemodel (= 3.2.8)
38
+ activesupport (= 3.2.8)
39
+ activesupport (3.2.8)
40
+ i18n (~> 0.6)
41
+ multi_json (~> 1.0)
42
+ arel (3.0.2)
43
+ builder (3.0.4)
44
+ diff-lcs (1.1.3)
45
+ erubis (2.7.0)
46
+ hike (1.2.1)
47
+ i18n (0.6.1)
48
+ journey (1.0.4)
49
+ json (1.7.5)
50
+ mail (2.4.4)
51
+ i18n (>= 0.4.0)
52
+ mime-types (~> 1.16)
53
+ treetop (~> 1.4.8)
54
+ mime-types (1.19)
55
+ multi_json (1.3.7)
56
+ pg (0.14.1)
57
+ polyglot (0.3.3)
58
+ rack (1.4.1)
59
+ rack-cache (1.2)
60
+ rack (>= 0.4)
61
+ rack-ssl (1.3.2)
62
+ rack
63
+ rack-test (0.6.2)
64
+ rack (>= 1.0)
65
+ rails (3.2.8)
66
+ actionmailer (= 3.2.8)
67
+ actionpack (= 3.2.8)
68
+ activerecord (= 3.2.8)
69
+ activeresource (= 3.2.8)
70
+ activesupport (= 3.2.8)
71
+ bundler (~> 1.0)
72
+ railties (= 3.2.8)
73
+ railties (3.2.8)
74
+ actionpack (= 3.2.8)
75
+ activesupport (= 3.2.8)
76
+ rack-ssl (~> 1.3.2)
77
+ rake (>= 0.8.7)
78
+ rdoc (~> 3.4)
79
+ thor (>= 0.14.6, < 2.0)
80
+ rake (0.9.2.2)
81
+ rdoc (3.12)
82
+ json (~> 1.4)
83
+ rspec (2.11.0)
84
+ rspec-core (~> 2.11.0)
85
+ rspec-expectations (~> 2.11.0)
86
+ rspec-mocks (~> 2.11.0)
87
+ rspec-core (2.11.1)
88
+ rspec-expectations (2.11.3)
89
+ diff-lcs (~> 1.1.3)
90
+ rspec-mocks (2.11.3)
91
+ sprockets (2.1.3)
92
+ hike (~> 1.2)
93
+ rack (~> 1.0)
94
+ tilt (~> 1.1, != 1.3.0)
95
+ thor (0.16.0)
96
+ tilt (1.3.3)
97
+ treetop (1.4.12)
98
+ polyglot
99
+ polyglot (>= 0.3.1)
100
+ tzinfo (0.3.34)
101
+
102
+ PLATFORMS
103
+ ruby
104
+
105
+ DEPENDENCIES
106
+ activerecord (~> 3.0)
107
+ activerecord-postgres-hstore (~> 0.4)
108
+ hstore_flags!
109
+ pg (~> 0.14)
110
+ rake
111
+ rspec (~> 2)
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ HStore Flags
2
+ ------------
3
+
4
+ integer/bit flags aggrevating you? try this.
5
+
6
+ Requirements
7
+ ------------
8
+
9
+ * Rails 3.0 or greater
10
+ * Postgresql 8.4+ with contrib package
11
+ * Read [activerecord-postgres-hstore](https://raw.github.com/engageis/activerecord-postgres-hstore) for index creation
12
+
13
+ Installation
14
+ ------------
15
+
16
+ TODO
17
+
18
+ Usage
19
+ -----
20
+
21
+ ```ruby
22
+ # defining flags
23
+ class User < ActiveRecord::Base
24
+ hstore_flags :active, :admin
25
+ hstore_flags :customer, :vendor, :drop_ship, field: "user_type"
26
+ end
27
+
28
+ class Group < ActiveRecord::Base
29
+ hstore_flags :active, :public, :invite_only, scopes: false
30
+ end
31
+
32
+ # setting flags
33
+ u = User.new
34
+ u.active = true
35
+ u.vendor = false
36
+
37
+ # automatic scope creation
38
+ User.active.to_sql #=> SELECT * FROM users WHERE (defined(flags, 'active') IS TRUE)
39
+ User.not_drop_ship.to_sql #=> SELECT * FROM users WHERE (defined(user_type, 'drop_ship') IS NOT TRUE)
40
+ ```
41
+
42
+ * `field` option defaults to `flags`
43
+ * `scopes: false` disables scope creation. though im not sure how useful that is
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ task :default => :spec
7
+
8
+ begin
9
+ Bundler.setup(:default, :development)
10
+ rescue Bundler::BundlerError => e
11
+ $stderr.puts e.message
12
+ $stderr.puts "Run `bundle install` to install missing gems"
13
+ exit e.status_code
14
+ end
15
+
16
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
2
+ require "hstore_flags/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "hstore_flags"
6
+ s.version = HStoreFlags::VERSION
7
+ s.summary = "Store many boolean flags in an hstore column in PostgreSQL"
8
+ s.authors = ["Zachery Hostens"]
9
+ s.email = "zachery.hostens@countrystone.com"
10
+ s.homepage = "https://github.com/infinitysw/hstore_flags"
11
+ s.files = `git ls-files`.split("\n")
12
+ s.license = "MIT"
13
+ s.require_paths = ["lib"]
14
+
15
+ s.add_dependency "activerecord", "~> 3.0"
16
+ s.add_dependency "activerecord-postgres-hstore", "~> 0.4"
17
+
18
+ s.add_development_dependency "rspec"
19
+ s.add_development_dependency "pg"
20
+ end
@@ -0,0 +1,60 @@
1
+ require 'hstore_flags/version'
2
+ require 'activerecord-postgres-hstore'
3
+
4
+ module HStoreFlags
5
+ TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE']
6
+
7
+ def self.included(base)
8
+ base.extend(ClassMethods)
9
+
10
+ protected
11
+ def set_hstore_flag_field(field, flag, value)
12
+ new_val = TRUE_VALUES.include?(value)
13
+ old_val = self.send(flag)
14
+ return if new_val == old_val
15
+
16
+ if defined? changed_attributes
17
+ send(:changed_attributes).merge!(flag.to_s => old_val)
18
+ end
19
+
20
+ if new_val
21
+ self[field] = (self[field] || {}).merge({flag.to_s => true.to_s})
22
+ else
23
+ self[field] && self[field].delete(flag.to_s)
24
+ end
25
+ send("#{field}_will_change!")
26
+ new_val
27
+ end
28
+ end
29
+
30
+ module ClassMethods
31
+ def hstore_flags(*args)
32
+ opts = args.last.is_a?(Hash) ? args.pop.dup : {}
33
+ field = opts[:field] || "flags"
34
+ table_field = "#{self.table_name}." + field
35
+
36
+ args.each do |flag|
37
+ define_method("#{flag}") {(self[field] || {})[flag.to_s] == "true"}
38
+ define_method("#{flag}?") {(self[field] || {})[flag.to_s] == "true"}
39
+ define_method("#{flag}=") {|val| set_hstore_flag_field(field, flag, val)}
40
+
41
+ unless opts[:scopes] == false
42
+ scope "#{flag}", where("defined(#{table_field}, '#{flag}') IS TRUE")
43
+ scope "not_#{flag}", where("defined(#{table_field}, '#{flag}') IS NOT TRUE")
44
+
45
+ class_eval <<-EVAL
46
+ def self.#{flag}_condition
47
+ "(defined(#{table_field}, '#{flag}') IS TRUE)"
48
+ end
49
+
50
+ def self.not_#{flag}_condition
51
+ "(defined(#{table_field}, '#{flag}') IS NOT TRUE)"
52
+ end
53
+ EVAL
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ ActiveRecord::Base.send(:include, HStoreFlags)
@@ -0,0 +1,3 @@
1
+ module HStoreFlags
2
+ Version = VERSION = "0.0.3"
3
+ end
data/spec/database.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'active_record'
2
+
3
+ # connect
4
+ ActiveRecord::Base.establish_connection(
5
+ adapter: 'postgresql',
6
+ database: 'testing')
7
+
8
+ ActiveRecord::Base.connection.execute("CREATE EXTENSION IF NOT EXISTS hstore")
9
+
10
+ ActiveRecord::Schema.define(version: 1) do
11
+ execute "DROP TABLE IF EXISTS users"
12
+
13
+ create_table :users do |t|
14
+ t.column :flags, :hstore
15
+ t.column :more_flags, :hstore
16
+ end
17
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ class User < ActiveRecord::Base
4
+ hstore_flags :fighter, :lover
5
+ end
6
+
7
+ class UserNoScopes < ActiveRecord::Base
8
+ self.table_name = "users"
9
+ hstore_flags :fighter, :lover, :referee, scopes: false
10
+ end
11
+
12
+ class UserMultiFlags < ActiveRecord::Base
13
+ self.table_name = "users"
14
+ hstore_flags :fighter, :lover, :referee
15
+ hstore_flags :drinker, :smoker, :bartender, field: "more_flags"
16
+ end
17
+
18
+ describe HStoreFlags do
19
+ it "creates accessors for flags" do
20
+ u = User.new(fighter: true)
21
+ expect(u.fighter).to eq(true)
22
+ expect(u.fighter?).to eq(true)
23
+ expect(u.lover).to eq(false)
24
+ expect(u.lover?).to eq(false)
25
+ end
26
+
27
+ it "creates scopes without scopes: false" do
28
+ expect(User).to respond_to(:fighter)
29
+ expect(User).to respond_to(:not_fighter)
30
+ expect(User).to respond_to(:lover)
31
+ expect(User).to respond_to(:not_lover)
32
+ end
33
+
34
+ it "does not create scopes with scopes: false" do
35
+ expect(UserNoScopes).not_to respond_to(:fighter)
36
+ expect(UserNoScopes).not_to respond_to(:not_fighter)
37
+ expect(UserNoScopes).not_to respond_to(:lover)
38
+ expect(UserNoScopes).not_to respond_to(:not_lover)
39
+ end
40
+
41
+ it "creates proper scopes when no field is defined" do
42
+ expect(User.fighter.to_sql).to match(/defined\(users.flags, 'fighter'\) IS TRUE/)
43
+ expect(User.not_fighter.to_sql).to match(/defined\(users.flags, 'fighter'\) IS NOT TRUE/)
44
+ end
45
+
46
+ it "creates proper scopes when field is defined" do
47
+ expect(UserMultiFlags.drinker.to_sql).to match(/defined\(users.more_flags, 'drinker'\) IS TRUE/)
48
+ expect(UserMultiFlags.not_drinker.to_sql).to match(/defined\(users.more_flags, 'drinker'\) IS NOT TRUE/)
49
+ end
50
+
51
+ it "updates changes with new bit values" do
52
+ u = User.new
53
+ expect(u.changes[:fighter]).to eq(nil)
54
+ u.fighter = true
55
+ expect(u.changes[:fighter]).to eq([false, true])
56
+ u.fighter = false
57
+ expect(u.changes[:fighter]).to eq([true, false]) # this is wrong, it should disappear
58
+ end
59
+ end
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ if ENV['VERSION']
3
+ gem 'activesupport', ENV['VERSION']
4
+ gem 'activerecord', ENV['VERSION']
5
+ end
6
+
7
+ $LOAD_PATH.unshift File.dirname(__FILE__)
8
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
9
+
10
+ require 'active_record'
11
+ require 'hstore_flags'
12
+ require 'database'
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hstore_flags
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Zachery Hostens
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activerecord-postgres-hstore
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '0.4'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '0.4'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: pg
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description:
79
+ email: zachery.hostens@countrystone.com
80
+ executables: []
81
+ extensions: []
82
+ extra_rdoc_files: []
83
+ files:
84
+ - .gitignore
85
+ - Gemfile
86
+ - Gemfile.lock
87
+ - README.md
88
+ - Rakefile
89
+ - hstore_flags.gemspec
90
+ - lib/hstore_flags.rb
91
+ - lib/hstore_flags/version.rb
92
+ - spec/database.rb
93
+ - spec/hstore_flags_spec.rb
94
+ - spec/spec_helper.rb
95
+ homepage: https://github.com/infinitysw/hstore_flags
96
+ licenses:
97
+ - MIT
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ segments:
109
+ - 0
110
+ hash: 1999031587017127090
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ! '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ segments:
118
+ - 0
119
+ hash: 1999031587017127090
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 1.8.23
123
+ signing_key:
124
+ specification_version: 3
125
+ summary: Store many boolean flags in an hstore column in PostgreSQL
126
+ test_files: []