property_sets 0.5.6 → 0.5.8

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/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: