eav_hashes 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -20
- data/README.md +147 -147
- data/Rakefile +30 -30
- data/lib/eav_hashes/activerecord_extension.rb +37 -37
- data/lib/eav_hashes/eav_entry.rb +128 -128
- data/lib/eav_hashes/eav_hash.rb +167 -167
- data/lib/eav_hashes/util.rb +122 -122
- data/lib/eav_hashes/version.rb +5 -5
- data/lib/eav_hashes.rb +8 -8
- data/lib/generators/eav_migration/USAGE +26 -26
- data/lib/generators/eav_migration/eav_migration.rb +35 -35
- data/lib/generators/eav_migration/templates/eav_migration.erb +15 -15
- data/spec/dummy/README.rdoc +261 -261
- data/spec/dummy/Rakefile +7 -7
- data/spec/dummy/app/assets/javascripts/application.js +15 -15
- data/spec/dummy/app/assets/stylesheets/application.css +13 -13
- data/spec/dummy/app/controllers/application_controller.rb +3 -3
- data/spec/dummy/app/helpers/application_helper.rb +2 -2
- data/spec/dummy/app/models/custom_test_object.rb +6 -6
- data/spec/dummy/app/models/product.rb +3 -4
- data/spec/dummy/app/views/layouts/application.html.erb +14 -14
- data/spec/dummy/config/application.rb +62 -68
- data/spec/dummy/config/boot.rb +9 -9
- data/spec/dummy/config/database.yml +25 -25
- data/spec/dummy/config/environment.rb +5 -5
- data/spec/dummy/config/environments/development.rb +34 -37
- data/spec/dummy/config/environments/production.rb +70 -67
- data/spec/dummy/config/environments/test.rb +34 -37
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -7
- data/spec/dummy/config/initializers/inflections.rb +15 -15
- data/spec/dummy/config/initializers/mime_types.rb +5 -5
- data/spec/dummy/config/initializers/secret_token.rb +7 -7
- data/spec/dummy/config/initializers/session_store.rb +8 -8
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -14
- data/spec/dummy/config/locales/en.yml +5 -5
- data/spec/dummy/config/routes.rb +58 -58
- data/spec/dummy/config.ru +4 -4
- data/spec/dummy/db/migrate/20121206133059_create_products.rb +9 -9
- data/spec/dummy/db/migrate/20121210055854_create_product_tech_specs.rb +15 -15
- data/spec/dummy/db/seeds.rb +30 -30
- data/spec/dummy/public/404.html +26 -26
- data/spec/dummy/public/422.html +26 -26
- data/spec/dummy/public/500.html +25 -25
- data/spec/dummy/script/rails +6 -6
- data/spec/lib/eav_hashes/eav_hash_spec.rb +147 -137
- data/spec/lib/generators/eav_migration_spec.rb +60 -60
- data/spec/spec_helper.rb +24 -24
- metadata +25 -44
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +0 -35
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/ENV=test.log +0 -1
- data/spec/dummy/log/development.log +0 -46
- data/spec/dummy/log/test.log +0 -4623
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ae80ab5c3269d2d2d014229a916e6bd2d1f5887a
|
4
|
+
data.tar.gz: 5e90a1d6874451e1cf34ccfd88bce14e459b274d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 160c12fd33afa959a6597fa45c3e0d3edfa663d8fa7c33037fb0131e791180829dbc1c2fe1a43f8927a3f22e3e51cc6776bec16c0204e320513080677c03027d
|
7
|
+
data.tar.gz: bbd73843daaad8e0668a3ee1eba60eaabb20e80490bfe0d86203303b08ca4e44bb7d66720d4d67c7e3657acdb0bb57bad063b21d037fd928931f4cd9d9501075
|
data/MIT-LICENSE
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
Copyright 2012 Ilya Ostrovskiy
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
-
a copy of this software and associated documentation files (the
|
5
|
-
"Software"), to deal in the Software without restriction, including
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following conditions:
|
10
|
-
|
11
|
-
The above copyright notice and this permission notice shall be
|
12
|
-
included in all copies or substantial portions of the Software.
|
13
|
-
|
14
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1
|
+
Copyright 2012 Ilya Ostrovskiy
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,147 +1,147 @@
|
|
1
|
-
eav_hashes
|
2
|
-
=========
|
3
|
-
|
4
|
-
[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/
|
5
|
-
|
6
|
-
`eav_hashes` is a neato gem for implementing the EAV (entity-attribute-value)
|
7
|
-
database design pattern in your Rails models. All you need to do is add one
|
8
|
-
line to your model's code and that's it! Schema generation is automatically
|
9
|
-
handled for you.
|
10
|
-
|
11
|
-
Why would I need it?
|
12
|
-
-
|
13
|
-
Rails' ActiveRecord includes a helper function, `serialize`, to allow you to
|
14
|
-
save complex data types (like hashes) into your database. Unfortunately, it
|
15
|
-
isn't very useful. A lot of overhead is created from serialization and
|
16
|
-
deserialization, and you can't search by the contents of your hash. That's
|
17
|
-
where `eav_hashes` comes in.
|
18
|
-
|
19
|
-
How does it work?
|
20
|
-
-
|
21
|
-
Great question! Lets dive in with a simple code example, but first lets set up the gem.
|
22
|
-
|
23
|
-
Put this in your gemfile...
|
24
|
-
|
25
|
-
gem "eav_hashes", "~> 1.0.0"
|
26
|
-
|
27
|
-
...and update your bundle.
|
28
|
-
|
29
|
-
$ bundle install
|
30
|
-
|
31
|
-
|
32
|
-
Now, lets make this Rails model.
|
33
|
-
|
34
|
-
```ruby
|
35
|
-
class Product < ActiveRecord::Base
|
36
|
-
eav_hash_for :tech_specs
|
37
|
-
end
|
38
|
-
```
|
39
|
-
|
40
|
-
Now run this generator to create a migration:
|
41
|
-
|
42
|
-
$ rails generate eav_migration Product tech_specs
|
43
|
-
|
44
|
-
And run the migration:
|
45
|
-
|
46
|
-
$ rake db:migrate
|
47
|
-
|
48
|
-
Now watch the magic the happen:
|
49
|
-
|
50
|
-
```ruby
|
51
|
-
# Assuming this whole example is on a blank DB, of course
|
52
|
-
a_product = Product.new
|
53
|
-
a_product.tech_specs["Widget Power"] = "1.21 GW"
|
54
|
-
a_product.tech_specs["Battery Life (hours)"] = 12
|
55
|
-
a_product.tech_specs["Warranty (years)"] = 3.5
|
56
|
-
a_product.tech_specs["RoHS Compliant"] = true
|
57
|
-
a_product.save!
|
58
|
-
|
59
|
-
# Setting a value to nil deletes the entry
|
60
|
-
a_product.tech_specs["Warranty (years)"] = nil
|
61
|
-
a_product.save!
|
62
|
-
|
63
|
-
the_same_product = Product.first
|
64
|
-
puts the_same_product.tech_specs["nonexistant key"]
|
65
|
-
|
66
|
-
# magic alert: this actually gets the count of EVERY entry of every
|
67
|
-
# hash for this model, but for this example this works
|
68
|
-
puts "Entry Count: #{ProductTechSpecsEntry.count}"
|
69
|
-
the_same_product.tech_specs.each_pair do |key, value|
|
70
|
-
puts "#{key}: #{value.to_s}"
|
71
|
-
end
|
72
|
-
|
73
|
-
# Ruby's default types: Integer, Float, Complex, Rational, Symbol,
|
74
|
-
# TrueClass, and FalseClass are preserved between transactions like
|
75
|
-
# you would expect them to.
|
76
|
-
puts the_same_product.tech_specs["Battery Life (hours)"]+3
|
77
|
-
```
|
78
|
-
|
79
|
-
And the output, as you can expect, will be along the lines of:
|
80
|
-
|
81
|
-
nil
|
82
|
-
Entry Count: 3
|
83
|
-
Widget Power: 1.21 GW
|
84
|
-
Battery Life (hours): 12
|
85
|
-
RoHS Compliant: true
|
86
|
-
15
|
87
|
-
|
88
|
-
|
89
|
-
That looks incredibly simple, right? Good! It's supposed to be! All the magic
|
90
|
-
happens when you call `save!`.
|
91
|
-
|
92
|
-
Now you could start doing other cool stuff, like searching for products based
|
93
|
-
on their tech specs! You've already figured out how to do this, haven't you?
|
94
|
-
|
95
|
-
```ruby
|
96
|
-
flux_capacitor = Product.find_by_tech_specs("Widget Power", "1.21 GW")
|
97
|
-
```
|
98
|
-
|
99
|
-
Nifty, right?
|
100
|
-
|
101
|
-
Can I store arrays/hashes/custom types inside my hashes?
|
102
|
-
--
|
103
|
-
Sure, but they'll be serialized into YAML (so you cant search by them like you
|
104
|
-
would an eav_hash). The `value` column is a TEXT type by default but if you
|
105
|
-
want to optimize your DB size you could change it to a VARCHAR in the migration
|
106
|
-
if you don't plan on storing large values.
|
107
|
-
|
108
|
-
|
109
|
-
What if I want to change the table name?
|
110
|
-
--
|
111
|
-
By default, `eav_hash` uses a table name derived from the following:
|
112
|
-
|
113
|
-
```ruby
|
114
|
-
"<ClassName>_<hash_name>".tableize
|
115
|
-
```
|
116
|
-
|
117
|
-
You can change this by passing a symbol to the `:table_name` argument:
|
118
|
-
|
119
|
-
```ruby
|
120
|
-
class Widget < ActiveRecord::Base
|
121
|
-
eav_hash_for :foobar, table_name: :bar_foo
|
122
|
-
end
|
123
|
-
```
|
124
|
-
|
125
|
-
Just remember to edit the table name in the migration, or use the following
|
126
|
-
migration generator:
|
127
|
-
|
128
|
-
$ rails generate eav_migration Widget foobar bar_foo
|
129
|
-
|
130
|
-
|
131
|
-
What's the catch?
|
132
|
-
-
|
133
|
-
By using this software, you agree to write me into your will as your next of
|
134
|
-
kin, and to sacrifice the soul of your first born child to Beelzebub.
|
135
|
-
|
136
|
-
Just kidding, the code is released under the MIT license so you can use it for
|
137
|
-
whatever purposes you see fit. Just don't sue me if your application blows up
|
138
|
-
from the sheer awesomeness! Check out the LICENSE file for more information.
|
139
|
-
|
140
|
-
Special Thanks!
|
141
|
-
-
|
142
|
-
Thanks to [Matt Kimmel](https://github.com/mattkimmel) for adding support for models contained in namespaces.
|
143
|
-
|
144
|
-
I found a bug or want to contribute!
|
145
|
-
-
|
146
|
-
You're probably reading this from GitHub, so you know what to do. If not, the
|
147
|
-
Github project is at https://github.com/
|
1
|
+
eav_hashes
|
2
|
+
=========
|
3
|
+
|
4
|
+
[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/iostat/eav_hashes) [![Build Status](https://travis-ci.org/iostat/eav_hashes.png?branch=master)](https://travis-ci.org/iostat/eav_hashes)
|
5
|
+
|
6
|
+
`eav_hashes` is a neato gem for implementing the EAV (entity-attribute-value)
|
7
|
+
database design pattern in your Rails models. All you need to do is add one
|
8
|
+
line to your model's code and that's it! Schema generation is automatically
|
9
|
+
handled for you.
|
10
|
+
|
11
|
+
Why would I need it?
|
12
|
+
-
|
13
|
+
Rails' ActiveRecord includes a helper function, `serialize`, to allow you to
|
14
|
+
save complex data types (like hashes) into your database. Unfortunately, it
|
15
|
+
isn't very useful. A lot of overhead is created from serialization and
|
16
|
+
deserialization, and you can't search by the contents of your hash. That's
|
17
|
+
where `eav_hashes` comes in.
|
18
|
+
|
19
|
+
How does it work?
|
20
|
+
-
|
21
|
+
Great question! Lets dive in with a simple code example, but first lets set up the gem.
|
22
|
+
|
23
|
+
Put this in your gemfile...
|
24
|
+
|
25
|
+
gem "eav_hashes", "~> 1.0.0"
|
26
|
+
|
27
|
+
...and update your bundle.
|
28
|
+
|
29
|
+
$ bundle install
|
30
|
+
|
31
|
+
|
32
|
+
Now, lets make this Rails model.
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
class Product < ActiveRecord::Base
|
36
|
+
eav_hash_for :tech_specs
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
Now run this generator to create a migration:
|
41
|
+
|
42
|
+
$ rails generate eav_migration Product tech_specs
|
43
|
+
|
44
|
+
And run the migration:
|
45
|
+
|
46
|
+
$ rake db:migrate
|
47
|
+
|
48
|
+
Now watch the magic the happen:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
# Assuming this whole example is on a blank DB, of course
|
52
|
+
a_product = Product.new
|
53
|
+
a_product.tech_specs["Widget Power"] = "1.21 GW"
|
54
|
+
a_product.tech_specs["Battery Life (hours)"] = 12
|
55
|
+
a_product.tech_specs["Warranty (years)"] = 3.5
|
56
|
+
a_product.tech_specs["RoHS Compliant"] = true
|
57
|
+
a_product.save!
|
58
|
+
|
59
|
+
# Setting a value to nil deletes the entry
|
60
|
+
a_product.tech_specs["Warranty (years)"] = nil
|
61
|
+
a_product.save!
|
62
|
+
|
63
|
+
the_same_product = Product.first
|
64
|
+
puts the_same_product.tech_specs["nonexistant key"]
|
65
|
+
|
66
|
+
# magic alert: this actually gets the count of EVERY entry of every
|
67
|
+
# hash for this model, but for this example this works
|
68
|
+
puts "Entry Count: #{ProductTechSpecsEntry.count}"
|
69
|
+
the_same_product.tech_specs.each_pair do |key, value|
|
70
|
+
puts "#{key}: #{value.to_s}"
|
71
|
+
end
|
72
|
+
|
73
|
+
# Ruby's default types: Integer, Float, Complex, Rational, Symbol,
|
74
|
+
# TrueClass, and FalseClass are preserved between transactions like
|
75
|
+
# you would expect them to.
|
76
|
+
puts the_same_product.tech_specs["Battery Life (hours)"]+3
|
77
|
+
```
|
78
|
+
|
79
|
+
And the output, as you can expect, will be along the lines of:
|
80
|
+
|
81
|
+
nil
|
82
|
+
Entry Count: 3
|
83
|
+
Widget Power: 1.21 GW
|
84
|
+
Battery Life (hours): 12
|
85
|
+
RoHS Compliant: true
|
86
|
+
15
|
87
|
+
|
88
|
+
|
89
|
+
That looks incredibly simple, right? Good! It's supposed to be! All the magic
|
90
|
+
happens when you call `save!`.
|
91
|
+
|
92
|
+
Now you could start doing other cool stuff, like searching for products based
|
93
|
+
on their tech specs! You've already figured out how to do this, haven't you?
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
flux_capacitor = Product.find_by_tech_specs("Widget Power", "1.21 GW")
|
97
|
+
```
|
98
|
+
|
99
|
+
Nifty, right?
|
100
|
+
|
101
|
+
Can I store arrays/hashes/custom types inside my hashes?
|
102
|
+
--
|
103
|
+
Sure, but they'll be serialized into YAML (so you cant search by them like you
|
104
|
+
would an eav_hash). The `value` column is a TEXT type by default but if you
|
105
|
+
want to optimize your DB size you could change it to a VARCHAR in the migration
|
106
|
+
if you don't plan on storing large values.
|
107
|
+
|
108
|
+
|
109
|
+
What if I want to change the table name?
|
110
|
+
--
|
111
|
+
By default, `eav_hash` uses a table name derived from the following:
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
"<ClassName>_<hash_name>".tableize
|
115
|
+
```
|
116
|
+
|
117
|
+
You can change this by passing a symbol to the `:table_name` argument:
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
class Widget < ActiveRecord::Base
|
121
|
+
eav_hash_for :foobar, table_name: :bar_foo
|
122
|
+
end
|
123
|
+
```
|
124
|
+
|
125
|
+
Just remember to edit the table name in the migration, or use the following
|
126
|
+
migration generator:
|
127
|
+
|
128
|
+
$ rails generate eav_migration Widget foobar bar_foo
|
129
|
+
|
130
|
+
|
131
|
+
What's the catch?
|
132
|
+
-
|
133
|
+
By using this software, you agree to write me into your will as your next of
|
134
|
+
kin, and to sacrifice the soul of your first born child to Beelzebub.
|
135
|
+
|
136
|
+
Just kidding, the code is released under the MIT license so you can use it for
|
137
|
+
whatever purposes you see fit. Just don't sue me if your application blows up
|
138
|
+
from the sheer awesomeness! Check out the LICENSE file for more information.
|
139
|
+
|
140
|
+
Special Thanks!
|
141
|
+
-
|
142
|
+
Thanks to [Matt Kimmel](https://github.com/mattkimmel) for adding support for models contained in namespaces.
|
143
|
+
|
144
|
+
I found a bug or want to contribute!
|
145
|
+
-
|
146
|
+
You're probably reading this from GitHub, so you know what to do. If not, the
|
147
|
+
Github project is at https://github.com/iostat/eav_hashes
|
data/Rakefile
CHANGED
@@ -1,30 +1,30 @@
|
|
1
|
-
#!/usr/bin/env rake
|
2
|
-
begin
|
3
|
-
require 'bundler/setup'
|
4
|
-
rescue LoadError
|
5
|
-
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
-
end
|
7
|
-
|
8
|
-
begin
|
9
|
-
require 'rdoc/task'
|
10
|
-
rescue LoadError
|
11
|
-
require 'rdoc/rdoc'
|
12
|
-
require 'rake/rdoctask'
|
13
|
-
RDoc::Task = Rake::RDocTask
|
14
|
-
end
|
15
|
-
|
16
|
-
RDoc::Task.new(:rdoc) do |rdoc|
|
17
|
-
rdoc.rdoc_dir = 'rdoc'
|
18
|
-
rdoc.title = 'EavHashes'
|
19
|
-
rdoc.options << '--line-numbers'
|
20
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
-
end
|
22
|
-
|
23
|
-
Bundler::GemHelper.install_tasks
|
24
|
-
|
25
|
-
require "rspec/core"
|
26
|
-
require "rspec/core/rake_task"
|
27
|
-
|
28
|
-
RSpec::Core::RakeTask.new(:spec)
|
29
|
-
|
30
|
-
task :default => :spec
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'rdoc/task'
|
10
|
+
rescue LoadError
|
11
|
+
require 'rdoc/rdoc'
|
12
|
+
require 'rake/rdoctask'
|
13
|
+
RDoc::Task = Rake::RDocTask
|
14
|
+
end
|
15
|
+
|
16
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'EavHashes'
|
19
|
+
rdoc.options << '--line-numbers'
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
Bundler::GemHelper.install_tasks
|
24
|
+
|
25
|
+
require "rspec/core"
|
26
|
+
require "rspec/core/rake_task"
|
27
|
+
|
28
|
+
RSpec::Core::RakeTask.new(:spec)
|
29
|
+
|
30
|
+
task :default => :spec
|
@@ -1,37 +1,37 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module EavHashes
|
3
|
-
def self.included (base)
|
4
|
-
base.extend ActiveRecord::EavHashes::ClassMethods
|
5
|
-
end
|
6
|
-
|
7
|
-
module ClassMethods
|
8
|
-
def eav_hash_for (hash_name, options={})
|
9
|
-
# Fill in default options not otherwise specified
|
10
|
-
options[:hash_name] = hash_name
|
11
|
-
options[:parent_class_name] = self.name.to_sym
|
12
|
-
options = ActiveRecord::EavHashes::Util::fill_options_hash options
|
13
|
-
|
14
|
-
# Store the options hash in a class variable to create the EavHash object
|
15
|
-
# if and when it's actually used.
|
16
|
-
class_variable_set "@@#{hash_name}_hash_options".to_sym, options
|
17
|
-
|
18
|
-
# Create the association, the entry update hook, and a helper method to lazy-load the entries
|
19
|
-
class_eval <<-END_EVAL
|
20
|
-
has_many :#{options[:entry_assoc_name]}, class_name: #{options[:entry_class_name]}, foreign_key: "#{options[:parent_assoc_name]}_id", dependent: :delete_all
|
21
|
-
after_save :save_#{hash_name}
|
22
|
-
def #{hash_name}
|
23
|
-
@#{hash_name} ||= ActiveRecord::EavHashes::EavHash.new(self, @@#{hash_name}_hash_options)
|
24
|
-
end
|
25
|
-
|
26
|
-
def save_#{hash_name}
|
27
|
-
@#{hash_name}.save_entries if @#{hash_name}
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.find_by_#{hash_name} (key, value=nil)
|
31
|
-
self.find (ActiveRecord::EavHashes::Util::run_find_expression(key, value, @@#{hash_name}_hash_options))
|
32
|
-
end
|
33
|
-
END_EVAL
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
1
|
+
module ActiveRecord
|
2
|
+
module EavHashes
|
3
|
+
def self.included (base)
|
4
|
+
base.extend ActiveRecord::EavHashes::ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def eav_hash_for (hash_name, options={})
|
9
|
+
# Fill in default options not otherwise specified
|
10
|
+
options[:hash_name] = hash_name
|
11
|
+
options[:parent_class_name] = self.name.to_sym
|
12
|
+
options = ActiveRecord::EavHashes::Util::fill_options_hash options
|
13
|
+
|
14
|
+
# Store the options hash in a class variable to create the EavHash object
|
15
|
+
# if and when it's actually used.
|
16
|
+
class_variable_set "@@#{hash_name}_hash_options".to_sym, options
|
17
|
+
|
18
|
+
# Create the association, the entry update hook, and a helper method to lazy-load the entries
|
19
|
+
class_eval <<-END_EVAL
|
20
|
+
has_many :#{options[:entry_assoc_name]}, class_name: #{options[:entry_class_name]}, foreign_key: "#{options[:parent_assoc_name]}_id", dependent: :delete_all
|
21
|
+
after_save :save_#{hash_name}
|
22
|
+
def #{hash_name}
|
23
|
+
@#{hash_name} ||= ActiveRecord::EavHashes::EavHash.new(self, @@#{hash_name}_hash_options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def save_#{hash_name}
|
27
|
+
@#{hash_name}.save_entries if @#{hash_name}
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.find_by_#{hash_name} (key, value=nil)
|
31
|
+
self.find (ActiveRecord::EavHashes::Util::run_find_expression(key, value, @@#{hash_name}_hash_options))
|
32
|
+
end
|
33
|
+
END_EVAL
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|