property_sets 0.5.6 → 0.5.8

Sign up to get free protection for your applications and to get access to all the features.
data/Appraisals ADDED
@@ -0,0 +1,11 @@
1
+ appraise "rails2.3" do
2
+ gem "activerecord", "2.3.14"
3
+ gem "activesupport", "2.3.14"
4
+ gem "actionpack", "2.3.14"
5
+ end
6
+
7
+ appraise "rails3.2" do
8
+ gem "activerecord", "3.2.1"
9
+ gem "activesupport", "3.2.1"
10
+ gem "actionpack", "3.2.1"
11
+ end
data/Gemfile CHANGED
@@ -1,5 +1,7 @@
1
1
  source "http://rubygems.org"
2
- # Add dependencies required to use your gem here.
3
- # Example:
2
+
3
+ gem 'activerecord-jdbcmysql-adapter', '1.2.2', :platforms => :jruby
4
+ gem 'mysql', :platforms => :ruby
4
5
 
5
6
  gemspec
7
+
data/README.md ADDED
@@ -0,0 +1,113 @@
1
+ # Property sets [![Build Status](https://secure.travis-ci.org/morten/property_sets.png)](http://travis-ci.org/morten/property_sets)
2
+
3
+ This gem is a way for you to use a basic "key/value" store for storing attributes for a given model in a relational fashion where there's a row per attribute. Alternatively you'd need to add a new column per attribute to your main table, or serialize the attributes and their values using the [ActiveRecord 3.2 store](https://github.com/rails/rails/commit/85b64f98d100d37b3a232c315daa10fad37dccdc).
4
+
5
+ ## Description
6
+
7
+ You configure the allowed stored properties by specifying these in the model:
8
+
9
+ class Account < ActiveRecord::Base
10
+ property_set :settings do
11
+ property :version, :default => "v1.0"
12
+ property :featured, :protected => true
13
+ property :activated
14
+ end
15
+
16
+ property_set :texts do
17
+ property :epilogue
18
+ end
19
+ end
20
+
21
+ The declared properties can then be accessed runtime via the defined association:
22
+
23
+ # Return the value of the version record for this account, or the default value if not set
24
+ account.settings.version
25
+
26
+ # Update the version record with given value
27
+ account.settings.version = "v1.1"
28
+
29
+ # Query the truth value of the property
30
+ account.settings.featured?
31
+
32
+ # Short hand for setting one or more values
33
+ account.settings.set(:version => "v1.2", :activated => true)
34
+
35
+ ### Validations
36
+
37
+ Property sets supports standard AR validations, although in a somewhat manual fashion.
38
+
39
+ class Account < ActiveRecord::Base
40
+ property_set :settings do
41
+ property :version, :default => "v1.0"
42
+ property :featured, :protected => true
43
+
44
+ validates_format_of :value, :with => /v\d+\.\d+/, :message => "of version is invalid",
45
+ :if => Proc.new { |r| r.name.to_sym == :version }
46
+ end
47
+ end
48
+
49
+ On +account.save+ this will result in an error record being added. You can also inspect the
50
+ setting record using +account.settings.version_record+
51
+
52
+ ### Bulk operations
53
+
54
+ Stored properties can also be updated with the update_attributes and update_attributes! methods by
55
+ enabling nested attributes. Like this (from the test cases):
56
+
57
+ @account.texts_attributes = [
58
+ { :name => "foo", :value => "1" },
59
+ { :name => "bar", :value => "0" }
60
+ ]
61
+
62
+ And for existing records:
63
+
64
+ @account.update_attributes!(:texts_attributes => [
65
+ { :id => @account.texts.foo.id, :name => "foo", :value => "0" },
66
+ { :id => @account.texts.bar.id, :name => "bar", :value => "1" }
67
+ ])
68
+
69
+ Using nested attributes is subject to implementing your own security measures for mass update assignments.
70
+ Alternatively, it is possible to use a custom hash structure:
71
+
72
+ params = {
73
+ :settings => { :version => "v4.0", :featured => "1" },
74
+ :texts => { :epilogue => "Wibble wobble" }
75
+ }
76
+ @account.update_attributes(params)
77
+
78
+ The above will not update +featured+ as this has the protected flag set and is hence protected from
79
+ mass updates.
80
+
81
+ ### View helpers
82
+
83
+ We support a couple of convenience mechanisms for building forms and putting the values into the above hash structure. So far, only support check boxes and radio buttons:
84
+
85
+ <% form_for(:account, :html => { :method => :put }) do |f| %>
86
+ <h3><%= f.property_set(:settings).check_box :activated %> Activated?</h3>
87
+ <h3><%= f.property_set(:settings).radio_button :hot, "yes" %> Hot</h3>
88
+ <h3><%= f.property_set(:settings).radio_button :not, "no" %> Not</h3>
89
+ <h3><%= f.property_set(:settings).select :level, [["One", 1], ["Two", 2]] %></h3>
90
+ <% end %>
91
+
92
+ ## Installation
93
+
94
+ Install the gem in your rails project by putting it in your Gemfile:
95
+
96
+ gem "property_sets"
97
+
98
+ Also remember to create the storage table(s), if for example you are going to be using this with an accounts model and a "settings" property set, you can define the table like:
99
+
100
+ create_table :account_settings do |t|
101
+ t.integer :account_id, :null => false
102
+ t.string :name, :null => false
103
+ t.string :value
104
+ t.timestamps
105
+ end
106
+
107
+ add_index :account_settings, [ :account_id, :name ], :unique => true
108
+
109
+ ## Requirements
110
+
111
+ * ActiveRecord
112
+ * ActiveSupport
113
+
data/Rakefile CHANGED
@@ -1,4 +1,6 @@
1
1
  require 'rubygems'
2
+ require 'appraisal'
3
+ require 'bundler'
2
4
  require 'rake'
3
5
  require 'date'
4
6
 
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activerecord-jdbcmysql-adapter", "1.2.2", :platforms=>:jruby
6
+ gem "mysql", :platforms=>:ruby
7
+ gem "activerecord", "2.3.14"
8
+ gem "activesupport", "2.3.14"
9
+ gem "actionpack", "2.3.14"
10
+
11
+ gemspec :path=>"../"
@@ -0,0 +1,49 @@
1
+ PATH
2
+ remote: /Users/primdahl/Git/property_sets
3
+ specs:
4
+ property_sets (0.5.6)
5
+ actionpack (>= 2.3.14, < 3.3)
6
+ activerecord (>= 2.3.14, < 3.3)
7
+ activesupport (>= 2.3.14, < 3.3)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ actionpack (2.3.14)
13
+ activesupport (= 2.3.14)
14
+ rack (~> 1.1.0)
15
+ activerecord (2.3.14)
16
+ activesupport (= 2.3.14)
17
+ activerecord-jdbc-adapter (1.2.2)
18
+ activerecord-jdbcmysql-adapter (1.2.2)
19
+ activerecord-jdbc-adapter (~> 1.2.2)
20
+ jdbc-mysql (~> 5.1.0)
21
+ activesupport (2.3.14)
22
+ appraisal (0.4.0)
23
+ bundler
24
+ rake
25
+ jdbc-mysql (5.1.13)
26
+ metaclass (0.0.1)
27
+ mocha (0.10.3)
28
+ metaclass (~> 0.0.1)
29
+ mysql (2.8.1)
30
+ rack (1.1.3)
31
+ rake (0.9.2.2)
32
+ shoulda (2.11.3)
33
+
34
+ PLATFORMS
35
+ java
36
+ ruby
37
+
38
+ DEPENDENCIES
39
+ actionpack (= 2.3.14)
40
+ activerecord (= 2.3.14)
41
+ activerecord-jdbcmysql-adapter (= 1.2.2)
42
+ activesupport (= 2.3.14)
43
+ appraisal
44
+ bundler
45
+ mocha
46
+ mysql
47
+ property_sets!
48
+ rake
49
+ shoulda
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activerecord-jdbcmysql-adapter", "1.2.2", :platforms=>:jruby
6
+ gem "mysql", :platforms=>:ruby
7
+ gem "activerecord", "3.2.1"
8
+ gem "activesupport", "3.2.1"
9
+ gem "actionpack", "3.2.1"
10
+
11
+ gemspec :path=>"../"
@@ -0,0 +1,81 @@
1
+ PATH
2
+ remote: /Users/primdahl/Git/property_sets
3
+ specs:
4
+ property_sets (0.5.6)
5
+ actionpack (>= 2.3.14, < 3.3)
6
+ activerecord (>= 2.3.14, < 3.3)
7
+ activesupport (>= 2.3.14, < 3.3)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ actionpack (3.2.1)
13
+ activemodel (= 3.2.1)
14
+ activesupport (= 3.2.1)
15
+ builder (~> 3.0.0)
16
+ erubis (~> 2.7.0)
17
+ journey (~> 1.0.1)
18
+ rack (~> 1.4.0)
19
+ rack-cache (~> 1.1)
20
+ rack-test (~> 0.6.1)
21
+ sprockets (~> 2.1.2)
22
+ activemodel (3.2.1)
23
+ activesupport (= 3.2.1)
24
+ builder (~> 3.0.0)
25
+ activerecord (3.2.1)
26
+ activemodel (= 3.2.1)
27
+ activesupport (= 3.2.1)
28
+ arel (~> 3.0.0)
29
+ tzinfo (~> 0.3.29)
30
+ activerecord-jdbc-adapter (1.2.2)
31
+ activerecord-jdbcmysql-adapter (1.2.2)
32
+ activerecord-jdbc-adapter (~> 1.2.2)
33
+ jdbc-mysql (~> 5.1.0)
34
+ activesupport (3.2.1)
35
+ i18n (~> 0.6)
36
+ multi_json (~> 1.0)
37
+ appraisal (0.4.0)
38
+ bundler
39
+ rake
40
+ arel (3.0.0)
41
+ builder (3.0.0)
42
+ erubis (2.7.0)
43
+ hike (1.2.1)
44
+ i18n (0.6.0)
45
+ jdbc-mysql (5.1.13)
46
+ journey (1.0.1)
47
+ metaclass (0.0.1)
48
+ mocha (0.10.3)
49
+ metaclass (~> 0.0.1)
50
+ multi_json (1.0.4)
51
+ mysql (2.8.1)
52
+ rack (1.4.1)
53
+ rack-cache (1.1)
54
+ rack (>= 0.4)
55
+ rack-test (0.6.1)
56
+ rack (>= 1.0)
57
+ rake (0.9.2.2)
58
+ shoulda (2.11.3)
59
+ sprockets (2.1.2)
60
+ hike (~> 1.2)
61
+ rack (~> 1.0)
62
+ tilt (~> 1.1, != 1.3.0)
63
+ tilt (1.3.3)
64
+ tzinfo (0.3.31)
65
+
66
+ PLATFORMS
67
+ java
68
+ ruby
69
+
70
+ DEPENDENCIES
71
+ actionpack (= 3.2.1)
72
+ activerecord (= 3.2.1)
73
+ activerecord-jdbcmysql-adapter (= 1.2.2)
74
+ activesupport (= 3.2.1)
75
+ appraisal
76
+ bundler
77
+ mocha
78
+ mysql
79
+ property_sets!
80
+ rake
81
+ shoulda
data/lib/property_sets.rb CHANGED
@@ -3,7 +3,7 @@ require 'property_sets/active_record_extension'
3
3
  require 'property_sets/action_view_extension'
4
4
 
5
5
  module PropertySets
6
- VERSION = "0.5.6"
6
+ VERSION = "0.5.8"
7
7
 
8
8
  def self.ensure_property_set_class(association, owner_class)
9
9
  const_name = "#{owner_class.name}#{association.to_s.singularize.capitalize}".to_sym
@@ -1,6 +1,9 @@
1
+ require 'property_sets/casting'
2
+
1
3
  module PropertySets
2
4
  module ActiveRecordExtension
3
5
  module ClassMethods
6
+
4
7
  def property_set(association, &block)
5
8
  unless include?(PropertySets::ActiveRecordExtension::InstanceMethods)
6
9
  self.send(:include, PropertySets::ActiveRecordExtension::InstanceMethods)
@@ -28,37 +31,6 @@ module PropertySets
28
31
  end
29
32
  end
30
33
 
31
- def read_value_cast_for_property_set(type, value)
32
- return nil if value.nil?
33
-
34
- case type
35
- when :string
36
- value
37
- when :datetime
38
- Time.parse(value).in_time_zone
39
- when :float
40
- value.to_f
41
- when :integer
42
- value.to_i
43
- when :boolean
44
- ![ "false", "0", "", "off", "n" ].member?(value.to_s.downcase)
45
- end
46
- end
47
-
48
- def write_value_cast_for_property_set(type, value)
49
- return nil if value.nil?
50
- case type
51
- when :datetime
52
- if value.is_a?(String)
53
- value
54
- else
55
- value.in_time_zone("UTC").to_s
56
- end
57
- else
58
- value.to_s
59
- end
60
- end
61
-
62
34
  property_class.keys.each do |key|
63
35
  raise "Invalid property key #{key}" if self.respond_to?(key)
64
36
 
@@ -69,13 +41,13 @@ module PropertySets
69
41
 
70
42
  # Returns the value of the property
71
43
  define_method "#{key}" do
72
- read_value_cast_for_property_set(property_class.type(key), lookup(key).value)
44
+ PropertySets::Casting.read(property_class.type(key), lookup(key).value)
73
45
  end
74
46
 
75
47
  # Assigns a new value to the property
76
48
  define_method "#{key}=" do |value|
77
49
  instance = lookup(key)
78
- instance.value = write_value_cast_for_property_set(property_class.type(key), value)
50
+ instance.value = PropertySets::Casting.write(property_class.type(key), value)
79
51
  end
80
52
 
81
53
  define_method "#{key}_record" do
@@ -83,6 +55,14 @@ module PropertySets
83
55
  end
84
56
  end
85
57
 
58
+ def save(*args)
59
+ each { |p| p.save(*args) }
60
+ end
61
+
62
+ def save!(*args)
63
+ each { |p| p.save!(*args) }
64
+ end
65
+
86
66
  def protected?(arg)
87
67
  lookup(arg).protected?
88
68
  end
@@ -108,17 +88,28 @@ module PropertySets
108
88
  instance = lookup_without_default(arg)
109
89
  instance ||= build_default(arg)
110
90
 
111
- instance.send("#{owner_class_sym}=", @owner) if @owner.new_record?
91
+ if ActiveRecord::VERSION::MAJOR == 3
92
+ owner = proxy_association.owner
93
+ else
94
+ owner = @owner
95
+ end
112
96
 
97
+ instance.send("#{owner_class_sym}=", owner) if owner.new_record?
113
98
  instance
114
99
  end
115
100
 
116
- # This finder method returns the property if present,
117
- # otherwise a new instance with the default value.
101
+ # This finder method returns the property if present, otherwise a new instance with the default value.
118
102
  # It does not have the side effect of adding a new setting object.
119
103
  def lookup_or_default(arg)
120
- instance = detect { |property| property.name.to_sym == arg.to_sym }
121
- instance ||= new(:value => default(arg))
104
+ instance = detect { |property| property.name.to_sym == arg.to_sym }
105
+ instance ||= begin
106
+ if ActiveRecord::VERSION::MAJOR == 3
107
+ association_class = proxy_association.klass
108
+ else
109
+ association_class = @reflection.klass
110
+ end
111
+ association_class.new(:value => default(arg))
112
+ end
122
113
  end
123
114
  end
124
115
  end
@@ -0,0 +1,37 @@
1
+ module PropertySets
2
+ module Casting
3
+
4
+ def self.read(type, value)
5
+ return nil if value.nil?
6
+
7
+ case type
8
+ when :string
9
+ value
10
+ when :datetime
11
+ Time.parse(value).in_time_zone
12
+ when :float
13
+ value.to_f
14
+ when :integer
15
+ value.to_i
16
+ when :boolean
17
+ ![ "false", "0", "", "off", "n" ].member?(value.to_s.downcase)
18
+ end
19
+ end
20
+
21
+ def self.write(type, value)
22
+ return nil if value.nil?
23
+
24
+ case type
25
+ when :datetime
26
+ if value.is_a?(String)
27
+ value
28
+ else
29
+ value.in_time_zone("UTC").to_s
30
+ end
31
+ else
32
+ value.to_s
33
+ end
34
+ end
35
+
36
+ end
37
+ end
@@ -7,14 +7,14 @@
7
7
  Gem::Specification.new do |s|
8
8
  s.specification_version = 2 if s.respond_to? :specification_version=
9
9
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
10
- s.rubygems_version = '1.3.5'
10
+ s.rubygems_version = '1.8.15'
11
11
 
12
12
  ## Leave these as is they will be modified for you by the rake gemspec task.
13
13
  ## If your rubyforge_project name is different, then edit it and comment out
14
14
  ## the sub! line in the Rakefile
15
15
  s.name = 'property_sets'
16
- s.version = '0.5.6'
17
- s.date = '2011-11-30'
16
+ s.version = '0.5.8'
17
+ s.date = '2012-02-08'
18
18
  s.rubyforge_project = 'property_sets'
19
19
 
20
20
  ## Make sure your summary is short. The description may be as long
@@ -43,13 +43,13 @@ Gem::Specification.new do |s|
43
43
  ## Specify any RDoc options here. You'll want to add your README and
44
44
  ## LICENSE files to the extra_rdoc_files list.
45
45
  s.rdoc_options = ["--charset=UTF-8"]
46
- s.extra_rdoc_files = %w[README.rdoc LICENSE.txt]
46
+ s.extra_rdoc_files = %w[README.md LICENSE.txt]
47
47
 
48
48
  ## List your runtime dependencies here. Runtime dependencies are those
49
49
  ## that are needed for an end user to actually USE your code.
50
- s.add_runtime_dependency("activesupport", ["~> 2.3.14"])
51
- s.add_runtime_dependency("activerecord", ["~> 2.3.14"])
52
- s.add_runtime_dependency("actionpack", ["~> 2.3.14"])
50
+ s.add_runtime_dependency("activesupport", ">= 2.3.14", "< 3.3")
51
+ s.add_runtime_dependency("activerecord", ">= 2.3.14", "< 3.3")
52
+ s.add_runtime_dependency("actionpack", ">= 2.3.14", "< 3.3")
53
53
 
54
54
  ## List your development dependencies here. Development dependencies are
55
55
  ## those that are only needed during development
@@ -57,30 +57,34 @@ Gem::Specification.new do |s|
57
57
  s.add_development_dependency('bundler')
58
58
  s.add_development_dependency('shoulda')
59
59
  s.add_development_dependency('mocha')
60
- s.add_development_dependency('sqlite3')
60
+ s.add_development_dependency("appraisal")
61
61
 
62
62
  ## Leave this section as-is. It will be automatically generated from the
63
63
  ## contents of your Git repository via the gemspec task. DO NOT REMOVE
64
64
  ## THE MANIFEST COMMENTS, they are used as delimiters by the task.
65
65
  # = MANIFEST =
66
66
  s.files = %w[
67
+ Appraisals
67
68
  Gemfile
68
- Gemfile.lock
69
69
  LICENSE.txt
70
- README.rdoc
70
+ README.md
71
71
  Rakefile
72
- db/.gitignore
72
+ gemfiles/rails2.3.gemfile
73
+ gemfiles/rails2.3.gemfile.lock
74
+ gemfiles/rails3.2.gemfile
75
+ gemfiles/rails3.2.gemfile.lock
73
76
  lib/property_sets.rb
74
77
  lib/property_sets/action_view_extension.rb
75
78
  lib/property_sets/active_record_extension.rb
79
+ lib/property_sets/casting.rb
76
80
  lib/property_sets/property_set_model.rb
77
81
  property_sets.gemspec
78
- test/database.yml
79
82
  test/fixtures/account_settings.yml
80
83
  test/fixtures/account_texts.yml
81
84
  test/fixtures/accounts.yml
82
85
  test/helper.rb
83
86
  test/schema.rb
87
+ test/test_casting.rb
84
88
  test/test_property_sets.rb
85
89
  test/test_view_extensions.rb
86
90
  ]
data/test/helper.rb CHANGED
@@ -5,9 +5,19 @@ require 'active_record'
5
5
  require 'active_record/fixtures'
6
6
  require 'shoulda'
7
7
 
8
- ActiveRecord::Base.configurations = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
9
- ActiveRecord::Base.establish_connection('test')
10
- ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/test.log")
8
+ ActiveRecord::Base.establish_connection(
9
+ :adapter => 'mysql',
10
+ :database => 'property_sets_test',
11
+ :username => 'root',
12
+ :password => nil,
13
+ :host => '127.0.0.1',
14
+ :port => 3306
15
+ )
16
+
17
+ ActiveRecord::Base.logger = Logger.new(STDOUT)
18
+ ActiveRecord::Base.logger.level = Logger::ERROR
19
+
20
+ ActiveRecord::Migration.verbose = false
11
21
 
12
22
  load(File.dirname(__FILE__) + "/schema.rb")
13
23
 
@@ -0,0 +1,29 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+ require 'property_sets/casting'
3
+
4
+ class TestCasting < ActiveSupport::TestCase
5
+
6
+ context "Casting#read" do
7
+ should "return nil when given value nil regardless of type" do
8
+ assert_equal nil, PropertySets::Casting.read(:string, nil)
9
+ assert_equal nil, PropertySets::Casting.read(:hello, nil)
10
+ end
11
+ end
12
+
13
+ context "Casting#write" do
14
+ should "return nil when given value nil regardless of type" do
15
+ assert_equal nil, PropertySets::Casting.write(:string, nil)
16
+ assert_equal nil, PropertySets::Casting.write(:hello, nil)
17
+ end
18
+
19
+ should "convert time instances to UTC" do
20
+ time = Time.now.in_time_zone("CET")
21
+ assert PropertySets::Casting.write(:datetime, time) =~ /UTC$/
22
+ end
23
+
24
+ should "convert integers to strings" do
25
+ assert_equal "123", PropertySets::Casting.write(:integer, 123)
26
+ end
27
+ end
28
+
29
+ end
@@ -127,7 +127,7 @@ class TestPropertySets < ActiveSupport::TestCase
127
127
  should "add an error when violated" do
128
128
  @account.validations.validated = "hello"
129
129
  assert !@account.valid?
130
- assert_equal "Value BEEP", @account.errors.full_messages.first
130
+ assert_match /BEEP$/, @account.errors.full_messages.first
131
131
  end
132
132
  end
133
133
 
@@ -236,6 +236,18 @@ class TestPropertySets < ActiveSupport::TestCase
236
236
  end
237
237
  end
238
238
 
239
+ context "save" do
240
+ should "call save on all dem records" do
241
+ @account.settings.foo = "1"
242
+ @account.settings.bar = "2"
243
+ @account.settings.save
244
+
245
+ @account.reload
246
+ assert_equal "1", @account.settings.foo
247
+ assert_equal "2", @account.settings.bar
248
+ end
249
+ end
250
+
239
251
  context "typed columns" do
240
252
  context "string data" do
241
253
  should "be writable and readable" do
@@ -6,7 +6,7 @@ class TestViewExtensions < ActiveSupport::TestCase
6
6
  setup do
7
7
  @association = :settings
8
8
  @property = :active
9
- @builder = ActionView::Helpers::FormBuilder.new("object_name", "object", "template", "options", "proc")
9
+ @builder = ActionView::Helpers::FormBuilder.new("object_name", "object", "template", {}, "proc")
10
10
  @proxy = @builder.property_set(@association)
11
11
  end
12
12
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: property_sets
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 5
9
- - 6
10
- version: 0.5.6
9
+ - 8
10
+ version: 0.5.8
11
11
  platform: ruby
12
12
  authors:
13
13
  - Morten Primdahl
@@ -15,16 +15,15 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-11-30 00:00:00 -08:00
19
- default_executable:
18
+ date: 2012-02-08 00:00:00 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
21
  name: activesupport
23
- type: :runtime
24
- version_requirements: &id001 !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
25
24
  none: false
26
25
  requirements:
27
- - - ~>
26
+ - - ">="
28
27
  - !ruby/object:Gem::Version
29
28
  hash: 31
30
29
  segments:
@@ -32,15 +31,22 @@ dependencies:
32
31
  - 3
33
32
  - 14
34
33
  version: 2.3.14
35
- prerelease: false
36
- requirement: *id001
34
+ - - <
35
+ - !ruby/object:Gem::Version
36
+ hash: 1
37
+ segments:
38
+ - 3
39
+ - 3
40
+ version: "3.3"
41
+ type: :runtime
42
+ version_requirements: *id001
37
43
  - !ruby/object:Gem::Dependency
38
44
  name: activerecord
39
- type: :runtime
40
- version_requirements: &id002 !ruby/object:Gem::Requirement
45
+ prerelease: false
46
+ requirement: &id002 !ruby/object:Gem::Requirement
41
47
  none: false
42
48
  requirements:
43
- - - ~>
49
+ - - ">="
44
50
  - !ruby/object:Gem::Version
45
51
  hash: 31
46
52
  segments:
@@ -48,15 +54,22 @@ dependencies:
48
54
  - 3
49
55
  - 14
50
56
  version: 2.3.14
51
- prerelease: false
52
- requirement: *id002
57
+ - - <
58
+ - !ruby/object:Gem::Version
59
+ hash: 1
60
+ segments:
61
+ - 3
62
+ - 3
63
+ version: "3.3"
64
+ type: :runtime
65
+ version_requirements: *id002
53
66
  - !ruby/object:Gem::Dependency
54
67
  name: actionpack
55
- type: :runtime
56
- version_requirements: &id003 !ruby/object:Gem::Requirement
68
+ prerelease: false
69
+ requirement: &id003 !ruby/object:Gem::Requirement
57
70
  none: false
58
71
  requirements:
59
- - - ~>
72
+ - - ">="
60
73
  - !ruby/object:Gem::Version
61
74
  hash: 31
62
75
  segments:
@@ -64,12 +77,19 @@ dependencies:
64
77
  - 3
65
78
  - 14
66
79
  version: 2.3.14
67
- prerelease: false
68
- requirement: *id003
80
+ - - <
81
+ - !ruby/object:Gem::Version
82
+ hash: 1
83
+ segments:
84
+ - 3
85
+ - 3
86
+ version: "3.3"
87
+ type: :runtime
88
+ version_requirements: *id003
69
89
  - !ruby/object:Gem::Dependency
70
90
  name: rake
71
- type: :development
72
- version_requirements: &id004 !ruby/object:Gem::Requirement
91
+ prerelease: false
92
+ requirement: &id004 !ruby/object:Gem::Requirement
73
93
  none: false
74
94
  requirements:
75
95
  - - ">="
@@ -78,12 +98,12 @@ dependencies:
78
98
  segments:
79
99
  - 0
80
100
  version: "0"
81
- prerelease: false
82
- requirement: *id004
101
+ type: :development
102
+ version_requirements: *id004
83
103
  - !ruby/object:Gem::Dependency
84
104
  name: bundler
85
- type: :development
86
- version_requirements: &id005 !ruby/object:Gem::Requirement
105
+ prerelease: false
106
+ requirement: &id005 !ruby/object:Gem::Requirement
87
107
  none: false
88
108
  requirements:
89
109
  - - ">="
@@ -92,12 +112,12 @@ dependencies:
92
112
  segments:
93
113
  - 0
94
114
  version: "0"
95
- prerelease: false
96
- requirement: *id005
115
+ type: :development
116
+ version_requirements: *id005
97
117
  - !ruby/object:Gem::Dependency
98
118
  name: shoulda
99
- type: :development
100
- version_requirements: &id006 !ruby/object:Gem::Requirement
119
+ prerelease: false
120
+ requirement: &id006 !ruby/object:Gem::Requirement
101
121
  none: false
102
122
  requirements:
103
123
  - - ">="
@@ -106,12 +126,12 @@ dependencies:
106
126
  segments:
107
127
  - 0
108
128
  version: "0"
109
- prerelease: false
110
- requirement: *id006
129
+ type: :development
130
+ version_requirements: *id006
111
131
  - !ruby/object:Gem::Dependency
112
132
  name: mocha
113
- type: :development
114
- version_requirements: &id007 !ruby/object:Gem::Requirement
133
+ prerelease: false
134
+ requirement: &id007 !ruby/object:Gem::Requirement
115
135
  none: false
116
136
  requirements:
117
137
  - - ">="
@@ -120,12 +140,12 @@ dependencies:
120
140
  segments:
121
141
  - 0
122
142
  version: "0"
123
- prerelease: false
124
- requirement: *id007
125
- - !ruby/object:Gem::Dependency
126
- name: sqlite3
127
143
  type: :development
128
- version_requirements: &id008 !ruby/object:Gem::Requirement
144
+ version_requirements: *id007
145
+ - !ruby/object:Gem::Dependency
146
+ name: appraisal
147
+ prerelease: false
148
+ requirement: &id008 !ruby/object:Gem::Requirement
129
149
  none: false
130
150
  requirements:
131
151
  - - ">="
@@ -134,8 +154,8 @@ dependencies:
134
154
  segments:
135
155
  - 0
136
156
  version: "0"
137
- prerelease: false
138
- requirement: *id008
157
+ type: :development
158
+ version_requirements: *id008
139
159
  description: This gem is an ActiveRecord extension which provides a convenient interface for managing per row properties.
140
160
  email: primdahl@me.com
141
161
  executables: []
@@ -143,29 +163,32 @@ executables: []
143
163
  extensions: []
144
164
 
145
165
  extra_rdoc_files:
146
- - README.rdoc
166
+ - README.md
147
167
  - LICENSE.txt
148
168
  files:
169
+ - Appraisals
149
170
  - Gemfile
150
- - Gemfile.lock
151
171
  - LICENSE.txt
152
- - README.rdoc
172
+ - README.md
153
173
  - Rakefile
154
- - db/.gitignore
174
+ - gemfiles/rails2.3.gemfile
175
+ - gemfiles/rails2.3.gemfile.lock
176
+ - gemfiles/rails3.2.gemfile
177
+ - gemfiles/rails3.2.gemfile.lock
155
178
  - lib/property_sets.rb
156
179
  - lib/property_sets/action_view_extension.rb
157
180
  - lib/property_sets/active_record_extension.rb
181
+ - lib/property_sets/casting.rb
158
182
  - lib/property_sets/property_set_model.rb
159
183
  - property_sets.gemspec
160
- - test/database.yml
161
184
  - test/fixtures/account_settings.yml
162
185
  - test/fixtures/account_texts.yml
163
186
  - test/fixtures/accounts.yml
164
187
  - test/helper.rb
165
188
  - test/schema.rb
189
+ - test/test_casting.rb
166
190
  - test/test_property_sets.rb
167
191
  - test/test_view_extensions.rb
168
- has_rdoc: true
169
192
  homepage: http://github.com/morten/property_sets
170
193
  licenses: []
171
194
 
@@ -195,10 +218,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
218
  requirements: []
196
219
 
197
220
  rubyforge_project: property_sets
198
- rubygems_version: 1.5.3
221
+ rubygems_version: 1.8.15
199
222
  signing_key:
200
223
  specification_version: 2
201
224
  summary: Property sets for ActiveRecord.
202
225
  test_files:
226
+ - test/test_casting.rb
203
227
  - test/test_property_sets.rb
204
228
  - test/test_view_extensions.rb
data/Gemfile.lock DELETED
@@ -1,33 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- property_sets (0.5.6)
5
- actionpack (~> 2.3.14)
6
- activerecord (~> 2.3.14)
7
- activesupport (~> 2.3.14)
8
-
9
- GEM
10
- remote: http://rubygems.org/
11
- specs:
12
- actionpack (2.3.14)
13
- activesupport (= 2.3.14)
14
- rack (~> 1.1.0)
15
- activerecord (2.3.14)
16
- activesupport (= 2.3.14)
17
- activesupport (2.3.14)
18
- mocha (0.9.12)
19
- rack (1.1.2)
20
- rake (0.9.2.2)
21
- shoulda (2.11.3)
22
- sqlite3 (1.3.3)
23
-
24
- PLATFORMS
25
- ruby
26
-
27
- DEPENDENCIES
28
- bundler
29
- mocha
30
- property_sets!
31
- rake
32
- shoulda
33
- sqlite3
data/README.rdoc DELETED
@@ -1,139 +0,0 @@
1
- = Property sets
2
-
3
- This gem is a way for you to use a basic "key/value" store for storing attributes for a given model in a relational fashion where there's a row per attribute. Alternatively you'd need to add a new column per attribute to your main table, or serialize the attributes and their values.
4
-
5
- == Description
6
-
7
- You configure the allowed stored properties by specifying these in the model:
8
-
9
- class Account < ActiveRecord::Base
10
- property_set :settings do
11
- property :version, :default => "v1.0"
12
- property :featured, :protected => true
13
- property :activated
14
- end
15
-
16
- property_set :texts do
17
- property :epilogue
18
- end
19
- end
20
-
21
- The declared properties can then be accessed runtime via the defined association:
22
-
23
- # Return the value of the version record for this account, or the default value if not set
24
- account.settings.version
25
-
26
- # Update the version record with given value
27
- account.settings.version = "v1.1"
28
-
29
- # Query the truth value of the property
30
- account.settings.featured?
31
-
32
- # Short hand for setting one or more values
33
- account.settings.set(:version => "v1.2", :activated => true)
34
-
35
- === Validations
36
-
37
- Property sets supports standard AR validations, although in a somewhat manual fashion.
38
-
39
- class Account < ActiveRecord::Base
40
- property_set :settings do
41
- property :version, :default => "v1.0"
42
- property :featured, :protected => true
43
-
44
- validates_format_of :value, :with => /v\d+\.\d+/, :message => "of version is invalid",
45
- :if => Proc.new { |r| r.name.to_sym == :version }
46
- end
47
- end
48
-
49
- On +account.save+ this will result in an error record being added. You can also inspect the
50
- setting record using +account.settings.version_record+
51
-
52
- === Bulk operations
53
-
54
- Stored properties can also be updated with the update_attributes and update_attributes! methods by
55
- enabling nested attributes. Like this (from the test cases):
56
-
57
- @account.texts_attributes = [
58
- { :name => "foo", :value => "1" },
59
- { :name => "bar", :value => "0" }
60
- ]
61
-
62
- And for existing records:
63
-
64
- @account.update_attributes!(:texts_attributes => [
65
- { :id => @account.texts.foo.id, :name => "foo", :value => "0" },
66
- { :id => @account.texts.bar.id, :name => "bar", :value => "1" }
67
- ])
68
-
69
- Using nested attributes is subject to implementing your own security measures for mass update assignments.
70
- Alternatively, it is possible to use a custom hash structure:
71
-
72
- params = {
73
- :settings => { :version => "v4.0", :featured => "1" },
74
- :texts => { :epilogue => "Wibble wobble" }
75
- }
76
- @account.update_attributes(params)
77
-
78
- The above will not update +featured+ as this has the protected flag set and is hence protected from
79
- mass updates.
80
-
81
- === View helpers
82
-
83
- We support a couple of convenience mechanisms for building forms and putting the values into the above hash structure. So far, only support check boxes and radio buttons:
84
-
85
- <% form_for(:account, :html => { :method => :put }) do |f| %>
86
- <h3><%= f.property_set(:settings).check_box :activated %> Activated?</h3>
87
- <h3><%= f.property_set(:settings).radio_button :hot, "yes" %> Hot</h3>
88
- <h3><%= f.property_set(:settings).radio_button :not, "no" %> Not</h3>
89
- <h3><%= f.property_set(:settings).select :level, [["One", 1], ["Two", 2]] %></h3>
90
- <% end %>
91
-
92
- == Installation
93
-
94
- Install the gem in your rails project by putting it in your Gemfile:
95
-
96
- gem "property_sets"
97
-
98
- Also remember to create the storage table(s), if for example you are going to be using this with an accounts model and a "settings" property set, you can define the table like:
99
-
100
- create_table :account_settings do |t|
101
- t.integer :account_id, :null => false
102
- t.string :name, :null => false
103
- t.string :value
104
- t.timestamps
105
- end
106
-
107
- add_index :account_settings, [ :account_id, :name ], :unique => true
108
-
109
- == Requirements
110
-
111
- * ActiveRecord
112
- * ActiveSupport
113
-
114
- == LICENSE:
115
-
116
- (The MIT License)
117
-
118
- Copyright (c) 2011 Zendesk
119
-
120
- Permission is hereby granted, free of charge, to any person
121
- obtaining a copy of this software and associated documentation
122
- files (the "Software"), to deal in the Software without
123
- restriction, including without limitation the rights to use,
124
- copy, modify, merge, publish, distribute, sublicense, and/or sell
125
- copies of the Software, and to permit persons to whom the
126
- Software is furnished to do so, subject to the following
127
- conditions:
128
-
129
- The above copyright notice and this permission notice shall be
130
- included in all copies or substantial portions of the Software.
131
-
132
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
133
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
134
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
135
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
136
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
137
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
138
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
139
- OTHER DEALINGS IN THE SOFTWARE.
data/db/.gitignore DELETED
@@ -1 +0,0 @@
1
- property_sets_test.sqlite
data/test/database.yml DELETED
@@ -1,6 +0,0 @@
1
- test:
2
- adapter: sqlite3
3
- encoding: utf8
4
- database: db/property_sets_test.sqlite
5
- username: root
6
- password: