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 +11 -0
- data/Gemfile +4 -2
- data/README.md +113 -0
- data/Rakefile +2 -0
- data/gemfiles/rails2.3.gemfile +11 -0
- data/gemfiles/rails2.3.gemfile.lock +49 -0
- data/gemfiles/rails3.2.gemfile +11 -0
- data/gemfiles/rails3.2.gemfile.lock +81 -0
- data/lib/property_sets.rb +1 -1
- data/lib/property_sets/active_record_extension.rb +29 -38
- data/lib/property_sets/casting.rb +37 -0
- data/property_sets.gemspec +16 -12
- data/test/helper.rb +13 -3
- data/test/test_casting.rb +29 -0
- data/test/test_property_sets.rb +13 -1
- data/test/test_view_extensions.rb +1 -1
- metadata +72 -48
- data/Gemfile.lock +0 -33
- data/README.rdoc +0 -139
- data/db/.gitignore +0 -1
- data/test/database.yml +0 -6
data/Appraisals
ADDED
data/Gemfile
CHANGED
data/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Property sets [](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
|
@@ -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
|
+
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
121
|
-
instance ||=
|
|
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
|
data/property_sets.gemspec
CHANGED
|
@@ -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.
|
|
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.
|
|
17
|
-
s.date = '
|
|
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.
|
|
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",
|
|
51
|
-
s.add_runtime_dependency("activerecord",
|
|
52
|
-
s.add_runtime_dependency("actionpack",
|
|
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(
|
|
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.
|
|
70
|
+
README.md
|
|
71
71
|
Rakefile
|
|
72
|
-
|
|
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.
|
|
9
|
-
|
|
10
|
-
|
|
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
|
data/test/test_property_sets.rb
CHANGED
|
@@ -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
|
-
|
|
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",
|
|
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:
|
|
4
|
+
hash: 27
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 0
|
|
8
8
|
- 5
|
|
9
|
-
-
|
|
10
|
-
version: 0.5.
|
|
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:
|
|
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
|
-
|
|
24
|
-
|
|
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
|
-
|
|
36
|
-
|
|
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
|
-
|
|
40
|
-
|
|
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
|
-
|
|
52
|
-
|
|
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
|
-
|
|
56
|
-
|
|
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
|
-
|
|
68
|
-
|
|
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
|
-
|
|
72
|
-
|
|
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
|
-
|
|
82
|
-
|
|
101
|
+
type: :development
|
|
102
|
+
version_requirements: *id004
|
|
83
103
|
- !ruby/object:Gem::Dependency
|
|
84
104
|
name: bundler
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
96
|
-
|
|
115
|
+
type: :development
|
|
116
|
+
version_requirements: *id005
|
|
97
117
|
- !ruby/object:Gem::Dependency
|
|
98
118
|
name: shoulda
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
|
|
110
|
-
|
|
129
|
+
type: :development
|
|
130
|
+
version_requirements: *id006
|
|
111
131
|
- !ruby/object:Gem::Dependency
|
|
112
132
|
name: mocha
|
|
113
|
-
|
|
114
|
-
|
|
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:
|
|
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
|
-
|
|
138
|
-
|
|
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.
|
|
166
|
+
- README.md
|
|
147
167
|
- LICENSE.txt
|
|
148
168
|
files:
|
|
169
|
+
- Appraisals
|
|
149
170
|
- Gemfile
|
|
150
|
-
- Gemfile.lock
|
|
151
171
|
- LICENSE.txt
|
|
152
|
-
- README.
|
|
172
|
+
- README.md
|
|
153
173
|
- Rakefile
|
|
154
|
-
-
|
|
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.
|
|
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
|