acts_as_eav_model 0.0.0

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.
Files changed (80) hide show
  1. data/.rvmrc +1 -0
  2. data/CHANGELOG +3 -0
  3. data/Gemfile +13 -0
  4. data/Gemfile.lock +92 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.rdoc +117 -0
  7. data/Rakefile +46 -0
  8. data/SPECDOC +23 -0
  9. data/TODO +0 -0
  10. data/VERSION +1 -0
  11. data/doc/classes/ActiveRecord/Acts/EavModel.html +213 -0
  12. data/doc/classes/ActiveRecord/Acts/EavModel/ClassMethods.html +343 -0
  13. data/doc/classes/ActiveRecord/Acts/EavModel/InstanceMethods.html +474 -0
  14. data/doc/classes/ActiveRecord/Acts/EavModel/InstanceMethods/ClassMethods.html +192 -0
  15. data/doc/classes/ActiveRecord/Base.html +170 -0
  16. data/doc/created.rid +1 -0
  17. data/doc/files/CHANGELOG.html +113 -0
  18. data/doc/files/MIT-LICENSE.html +129 -0
  19. data/doc/files/README_rdoc.html +248 -0
  20. data/doc/files/SPECDOC.html +170 -0
  21. data/doc/files/lib/acts_as_eav_model_rb.html +101 -0
  22. data/doc/fr_class_index.html +31 -0
  23. data/doc/fr_file_index.html +31 -0
  24. data/doc/fr_method_index.html +40 -0
  25. data/doc/index.html +24 -0
  26. data/doc/rdoc-style.css +208 -0
  27. data/init.rb +1 -0
  28. data/install.rb +1 -0
  29. data/lib/acts_as_eav_model.rb +542 -0
  30. data/spec/dummy/Rakefile +7 -0
  31. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  32. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  33. data/spec/dummy/app/models/document.rb +7 -0
  34. data/spec/dummy/app/models/person.rb +13 -0
  35. data/spec/dummy/app/models/person_contact_info.rb +2 -0
  36. data/spec/dummy/app/models/post.rb +4 -0
  37. data/spec/dummy/app/models/post_attribute.rb +2 -0
  38. data/spec/dummy/app/models/preference.rb +5 -0
  39. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  40. data/spec/dummy/config.ru +4 -0
  41. data/spec/dummy/config/application.rb +45 -0
  42. data/spec/dummy/config/boot.rb +10 -0
  43. data/spec/dummy/config/database.yml +22 -0
  44. data/spec/dummy/config/environment.rb +5 -0
  45. data/spec/dummy/config/environments/development.rb +26 -0
  46. data/spec/dummy/config/environments/production.rb +49 -0
  47. data/spec/dummy/config/environments/test.rb +35 -0
  48. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  49. data/spec/dummy/config/initializers/inflections.rb +10 -0
  50. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  51. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  52. data/spec/dummy/config/initializers/session_store.rb +8 -0
  53. data/spec/dummy/config/locales/en.yml +5 -0
  54. data/spec/dummy/config/routes.rb +58 -0
  55. data/spec/dummy/db/development.sqlite3 +0 -0
  56. data/spec/dummy/db/schema.rb +51 -0
  57. data/spec/dummy/public/404.html +26 -0
  58. data/spec/dummy/public/422.html +26 -0
  59. data/spec/dummy/public/500.html +26 -0
  60. data/spec/dummy/public/favicon.ico +0 -0
  61. data/spec/dummy/public/javascripts/application.js +2 -0
  62. data/spec/dummy/public/javascripts/controls.js +965 -0
  63. data/spec/dummy/public/javascripts/dragdrop.js +974 -0
  64. data/spec/dummy/public/javascripts/effects.js +1123 -0
  65. data/spec/dummy/public/javascripts/prototype.js +6001 -0
  66. data/spec/dummy/public/javascripts/rails.js +175 -0
  67. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  68. data/spec/dummy/script/rails +6 -0
  69. data/spec/fixtures/people.yml +4 -0
  70. data/spec/fixtures/person_contact_infos.yml +10 -0
  71. data/spec/fixtures/post_attributes.yml +15 -0
  72. data/spec/fixtures/posts.yml +9 -0
  73. data/spec/fixtures/preferences.yml +10 -0
  74. data/spec/models/eav_model_with_no_arguments_spec.rb +82 -0
  75. data/spec/models/eav_model_with_options_spec.rb +37 -0
  76. data/spec/models/eav_validation_spec.rb +11 -0
  77. data/spec/schema.rb +50 -0
  78. data/spec/spec_helper.rb +38 -0
  79. data/uninstall.rb +1 -0
  80. metadata +213 -0
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create use 1.9.2@acts_as_eav_model
@@ -0,0 +1,3 @@
1
+ * First version with base functionality to handle Entity-attribute-value model (EAV) pattern.
2
+
3
+ * CHANGELOG started [Marcus Wyatt]
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "rails", "3.0.1"
4
+ gem "sqlite3-ruby", :require => "sqlite3"
5
+ gem "jeweler"
6
+
7
+ if RUBY_VERSION < '1.9'
8
+ gem "ruby-debug", ">= 0.10.3"
9
+ end
10
+
11
+ group :test do
12
+ gem "rspec-rails", "~> 2.0"
13
+ end
@@ -0,0 +1,92 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ abstract (1.0.0)
5
+ actionmailer (3.0.1)
6
+ actionpack (= 3.0.1)
7
+ mail (~> 2.2.5)
8
+ actionpack (3.0.1)
9
+ activemodel (= 3.0.1)
10
+ activesupport (= 3.0.1)
11
+ builder (~> 2.1.2)
12
+ erubis (~> 2.6.6)
13
+ i18n (~> 0.4.1)
14
+ rack (~> 1.2.1)
15
+ rack-mount (~> 0.6.12)
16
+ rack-test (~> 0.5.4)
17
+ tzinfo (~> 0.3.23)
18
+ activemodel (3.0.1)
19
+ activesupport (= 3.0.1)
20
+ builder (~> 2.1.2)
21
+ i18n (~> 0.4.1)
22
+ activerecord (3.0.1)
23
+ activemodel (= 3.0.1)
24
+ activesupport (= 3.0.1)
25
+ arel (~> 1.0.0)
26
+ tzinfo (~> 0.3.23)
27
+ activeresource (3.0.1)
28
+ activemodel (= 3.0.1)
29
+ activesupport (= 3.0.1)
30
+ activesupport (3.0.1)
31
+ arel (1.0.1)
32
+ activesupport (~> 3.0.0)
33
+ builder (2.1.2)
34
+ diff-lcs (1.1.2)
35
+ erubis (2.6.6)
36
+ abstract (>= 1.0.0)
37
+ git (1.2.5)
38
+ i18n (0.4.2)
39
+ jeweler (1.5.1)
40
+ bundler (~> 1.0.0)
41
+ git (>= 1.2.5)
42
+ rake
43
+ mail (2.2.9)
44
+ activesupport (>= 2.3.6)
45
+ i18n (~> 0.4.1)
46
+ mime-types (~> 1.16)
47
+ treetop (~> 1.4.8)
48
+ mime-types (1.16)
49
+ polyglot (0.3.1)
50
+ rack (1.2.1)
51
+ rack-mount (0.6.13)
52
+ rack (>= 1.0.0)
53
+ rack-test (0.5.6)
54
+ rack (>= 1.0)
55
+ rails (3.0.1)
56
+ actionmailer (= 3.0.1)
57
+ actionpack (= 3.0.1)
58
+ activerecord (= 3.0.1)
59
+ activeresource (= 3.0.1)
60
+ activesupport (= 3.0.1)
61
+ bundler (~> 1.0.0)
62
+ railties (= 3.0.1)
63
+ railties (3.0.1)
64
+ actionpack (= 3.0.1)
65
+ activesupport (= 3.0.1)
66
+ rake (>= 0.8.4)
67
+ thor (~> 0.14.0)
68
+ rake (0.8.7)
69
+ rspec (2.1.0)
70
+ rspec-core (~> 2.1.0)
71
+ rspec-expectations (~> 2.1.0)
72
+ rspec-mocks (~> 2.1.0)
73
+ rspec-core (2.1.0)
74
+ rspec-expectations (2.1.0)
75
+ diff-lcs (~> 1.1.2)
76
+ rspec-mocks (2.1.0)
77
+ rspec-rails (2.1.0)
78
+ rspec (~> 2.1.0)
79
+ sqlite3-ruby (1.3.2)
80
+ thor (0.14.4)
81
+ treetop (1.4.8)
82
+ polyglot (>= 0.3.1)
83
+ tzinfo (0.3.23)
84
+
85
+ PLATFORMS
86
+ ruby
87
+
88
+ DEPENDENCIES
89
+ jeweler
90
+ rails (= 3.0.1)
91
+ rspec-rails (~> 2.0)
92
+ sqlite3-ruby
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Marcus Wyatt
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.
@@ -0,0 +1,117 @@
1
+ ActsAsEavModel
2
+ ==============
3
+
4
+ ActsAsEavModel allow for the Entity-attribute-value model (EAV), also
5
+ known as object-attribute-value model and open schema on any of your ActiveRecord
6
+ models.
7
+
8
+ = What is Entity-attribute-value model?
9
+ Entity-attribute-value model (EAV) is a data model that is used in circumstances
10
+ where the number of attributes (properties, parameters) that can be used to describe
11
+ a thing (an "entity" or "object") is potentially very vast, but the number that will
12
+ actually apply to a given entity is relatively modest.
13
+
14
+ = Typical Problem
15
+ A good example of this is where you need to store
16
+ lots (possible hundreds) of optional attributes on an object. My typical
17
+ reference example is when you have a User object. You want to store the
18
+ user's preferences between sessions. Every search, sort, etc in your
19
+ application you want to keep track of so when the user visits that section
20
+ of the application again you can simply restore the display to how it was.
21
+
22
+ So your controller might have:
23
+
24
+ Project.find :all, :conditions => current_user.project_search,
25
+ :order => current_user.project_order
26
+
27
+ But there could be hundreds of these little attributes that you really don't
28
+ want to store directly on the user object. It would make your table have too
29
+ many columns so it would be too much of a pain to deal with. Also there might
30
+ be performance problems. So instead you might do something like
31
+ this:
32
+
33
+ class User < ActiveRecord::Base
34
+ has_many :preferences
35
+ end
36
+
37
+ class Preferences < ActiveRecord::Base
38
+ belongs_to :user
39
+ end
40
+
41
+ Now simply give the Preference model a "name" and "value" column and you are
42
+ set..... except this is now too complicated. To retrieve a attribute you will
43
+ need to do something like:
44
+
45
+ Project.find :all,
46
+ :conditions => current_user.preferences.find_by_name('project_search').value,
47
+ :order => current_user.preferences.find_by_name('project_order').value
48
+
49
+ Sure you could fix this through a few methods on your model. But what about
50
+ saving?
51
+
52
+ current_user.preferences.create :name => 'project_search',
53
+ :value => "lastname LIKE 'jones%'"
54
+ current_user.preferences.create :name => 'project_order',
55
+ :value => "name"
56
+
57
+ Again this seems to much. Again we could add some methods to our model to
58
+ make this simpler but do we want to do this on every model. NO! So instead
59
+ we use this plugin which does everything for us.
60
+
61
+ = Capabilities
62
+
63
+ The ActsAsEavModel plugin is capable of modeling this problem in a intuitive
64
+ way. Instead of having to deal with a related model you treat all attributes
65
+ (both on the model and related) as if they are all on the model. The plugin
66
+ will try to save all attributes to the model (normal ActiveRecord behavior)
67
+ but if there is no column for an attribute it will try to save it to a
68
+ related model whose purpose is to store these many sparsely populated
69
+ attributes.
70
+
71
+ The main design goals are:
72
+
73
+ * Have the eav attributes feel like normal attributes. Simple gets and sets
74
+ will add and remove records from the related model.
75
+ * Allow for more than one related model. So for example on my User model I might
76
+ have some eav behavior going into a contact_info table while others are
77
+ going in a user_preferences table.
78
+ * Allow a model to determine what a valid eav attribute is for a given
79
+ related model so our model still can generate a NoMethodError.
80
+
81
+ Example
82
+ =======
83
+
84
+ Will make the current class have eav behaviour.
85
+
86
+ class Post < ActiveRecord::Base
87
+ has_eav_behavior
88
+ end
89
+ post = Post.find_by_title 'hello world'
90
+ puts "My post intro is: #{post.intro}"
91
+ post.teaser = 'An awesome introduction to the blog'
92
+ post.save
93
+
94
+ The above example should work even though "intro" and "teaser" are not
95
+ attributes on the Post model.
96
+
97
+ = Installation
98
+
99
+ ./script/plugin install acts_as_eav_model
100
+
101
+ = RUNNING UNIT TESTS
102
+
103
+ == Creating the test database
104
+
105
+ The test databases will be created from the info specified in test/database.yml.
106
+ Either change that file to match your database or change your database to
107
+ match that file.
108
+
109
+ == Running with Rake
110
+
111
+ The easiest way to run the unit tests is through Rake. By default sqlite3
112
+ will be the database run. Just change your env variable DB to be the database
113
+ adaptor (specified in database.yml) that you want to use. The database and
114
+ permissions must already be setup but the tables will be created for you
115
+ from schema.rb.
116
+
117
+ Copyright (c) 2008 Marcus Wyatt, released under the MIT license
@@ -0,0 +1,46 @@
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ require 'rake'
10
+ require 'rake/rdoctask'
11
+
12
+ require 'rspec/core'
13
+ require 'rspec/core/rake_task'
14
+
15
+ RSpec::Core::RakeTask.new(:spec)
16
+
17
+
18
+ Rake::RDocTask.new(:rdoc) do |rdoc|
19
+ rdoc.rdoc_dir = 'rdoc'
20
+ rdoc.title = 'Acts As EAV Model'
21
+ rdoc.options << '--line-numbers' << '--inline-source'
22
+ rdoc.rdoc_files.include('README.rdoc')
23
+ rdoc.rdoc_files.include('lib/**/*.rb')
24
+ end
25
+
26
+ begin
27
+ require 'jeweler'
28
+ Jeweler::Tasks.new do |gem|
29
+ gem.name = "acts_as_eav_model"
30
+ gem.summary = %Q{Entity Attribute Value Implementation for inclusion in ActiveRecord models.}
31
+ gem.description = %Q{Entity-attribute-value model (EAV) is a data model that is used in circumstances
32
+ where the number of attributes (properties, parameters) that can be used to describe
33
+ a thing (an "entity" or "object") is potentially very vast, but the number that will
34
+ actually apply to a given entity is relatively modest.}
35
+ gem.email = ""
36
+ gem.homepage = "http://github.com/g5search/acts_as_eav_model"
37
+ gem.has_rdoc=true
38
+ gem.authors = ["Marcus Wyatt"]
39
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
40
+ end
41
+ Jeweler::GemcutterTasks.new
42
+ rescue LoadError
43
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
44
+ end
45
+
46
+ task :default => :spec
data/SPECDOC ADDED
@@ -0,0 +1,23 @@
1
+
2
+ ActiveRecord Model annotated with 'has_eav_behavior' with no options in declaration
3
+ - should have many attributes
4
+ - should create new attribute on save
5
+ - should delete attribute
6
+ - should write eav attributes to attributes table
7
+ - should return nil when attribute does not exist
8
+ - should use method missing to make attribute seem as native property
9
+ - should read attributes using subscript notation
10
+ - should read the attribute when invoking 'read_attribute'
11
+
12
+ ActiveRecord Model annotated with 'has_eav_behavior' with options in declaration
13
+ - should be 'has_many' association on both sides
14
+ - should only allow restricted fields when specified (:fields => %w(phone aim icq))
15
+ - should raise 'NoMethodError' when attribute not in 'eav_attributes' method array
16
+ - should raise 'NoMethodError' when attribute does not satisfy 'is_eav_attribute?' method
17
+
18
+ Validations on ActiveRecord Model annotated with 'has_eav_behavior'
19
+ - should execute as normal (validates_presence_of)
20
+
21
+ Finished in 0.239663 seconds
22
+
23
+ 13 examples, 0 failures
data/TODO ADDED
File without changes
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1,213 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>Module: ActiveRecord::Acts::EavModel</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="classHeader">
50
+ <table class="header-table">
51
+ <tr class="top-aligned-row">
52
+ <td><strong>Module</strong></td>
53
+ <td class="class-name-in-header">ActiveRecord::Acts::EavModel</td>
54
+ </tr>
55
+ <tr class="top-aligned-row">
56
+ <td><strong>In:</strong></td>
57
+ <td>
58
+ <a href="../../../files/lib/acts_as_eav_model_rb.html">
59
+ lib/acts_as_eav_model.rb
60
+ </a>
61
+ <br />
62
+ </td>
63
+ </tr>
64
+
65
+ </table>
66
+ </div>
67
+ <!-- banner header -->
68
+
69
+ <div id="bodyContent">
70
+
71
+
72
+
73
+ <div id="contextContent">
74
+
75
+ <div id="description">
76
+ <p>
77
+ ActsAsEavModel allow for the Entity-attribute-value model (EAV), also known
78
+ as object-attribute-value model and open schema on any of your ActiveRecord
79
+ models.
80
+ </p>
81
+ <h1>What is Entity-attribute-value model?</h1>
82
+ <p>
83
+ Entity-attribute-value model (EAV) is a data model that is used in
84
+ circumstances where the number of attributes (properties, parameters) that
85
+ can be used to describe a thing (an &quot;entity&quot; or
86
+ &quot;object&quot;) is potentially very vast, but the number that will
87
+ actually apply to a given entity is relatively modest.
88
+ </p>
89
+ <h1>Typical Problem</h1>
90
+ <p>
91
+ A good example of this is where you need to store lots (possible hundreds)
92
+ of optional attributes on an object. My typical reference example is when
93
+ you have a User object. You want to store the user&#8216;s preferences
94
+ between sessions. Every search, sort, etc in your application you want to
95
+ keep track of so when the user visits that section of the application again
96
+ you can simply restore the display to how it was.
97
+ </p>
98
+ <p>
99
+ So your controller might have:
100
+ </p>
101
+ <pre>
102
+ Project.find :all, :conditions =&gt; current_user.project_search,
103
+ :order =&gt; current_user.project_order
104
+ </pre>
105
+ <p>
106
+ But there could be hundreds of these little attributes that you really
107
+ don&#8216;t want to store directly on the user object. It would make your
108
+ table have too many columns so it would be too much of a pain to deal with.
109
+ Also there might be performance problems. So instead you might do something
110
+ like this:
111
+ </p>
112
+ <pre>
113
+ class User &lt; ActiveRecord::Base
114
+ has_many :preferences
115
+ end
116
+
117
+ class Preferences &lt; ActiveRecord::Base
118
+ belongs_to :user
119
+ end
120
+ </pre>
121
+ <p>
122
+ Now simply give the Preference model a &quot;name&quot; and
123
+ &quot;value&quot; column and you are set.&#8230;. except this is now too
124
+ complicated. To retrieve a attribute you will need to do something like:
125
+ </p>
126
+ <pre>
127
+ Project.find :all,
128
+ :conditions =&gt; current_user.preferences.find_by_name('project_search').value,
129
+ :order =&gt; current_user.preferences.find_by_name('project_order').value
130
+ </pre>
131
+ <p>
132
+ Sure you could fix this through a few methods on your model. But what about
133
+ saving?
134
+ </p>
135
+ <pre>
136
+ current_user.preferences.create :name =&gt; 'project_search',
137
+ :value =&gt; &quot;lastname LIKE 'jones%'&quot;
138
+ current_user.preferences.create :name =&gt; 'project_order',
139
+ :value =&gt; &quot;name&quot;
140
+ </pre>
141
+ <p>
142
+ Again this seems to much. Again we could add some methods to our model to
143
+ make this simpler but do we want to do this on every model. NO! So instead
144
+ we use this plugin which does everything for us.
145
+ </p>
146
+ <h1>Capabilities</h1>
147
+ <p>
148
+ The ActsAsEavModel plugin is capable of modeling this problem in a
149
+ intuitive way. Instead of having to deal with a related model you treat all
150
+ attributes (both on the model and related) as if they are all on the model.
151
+ The plugin will try to save all attributes to the model (normal
152
+ ActiveRecord behaviour) but if there is no column for an attribute it will
153
+ try to save it to a related model whose purpose is to store these many
154
+ sparsly populated attributes.
155
+ </p>
156
+ <p>
157
+ The main design goals are:
158
+ </p>
159
+ <ul>
160
+ <li>Have the eav attributes feel like normal attributes. Simple gets and sets
161
+ will add and remove records from the related model.
162
+
163
+ </li>
164
+ <li>Allow for more than one related model. So for example on my User model I
165
+ might have some eav behavior going into a contact_info table while others
166
+ are going in a user_preferences table.
167
+
168
+ </li>
169
+ <li>Allow a model to determine what a valid eav attribute is for a given
170
+ related model so our model still can generate a NoMethodError.
171
+
172
+ </li>
173
+ </ul>
174
+
175
+ </div>
176
+
177
+
178
+ </div>
179
+
180
+
181
+ </div>
182
+
183
+
184
+ <!-- if includes -->
185
+
186
+ <div id="section">
187
+
188
+ <div id="class-list">
189
+ <h3 class="section-bar">Classes and Modules</h3>
190
+
191
+ Module <a href="EavModel/ClassMethods.html" class="link">ActiveRecord::Acts::EavModel::ClassMethods</a><br />
192
+ Module <a href="EavModel/InstanceMethods.html" class="link">ActiveRecord::Acts::EavModel::InstanceMethods</a><br />
193
+
194
+ </div>
195
+
196
+
197
+
198
+
199
+
200
+
201
+
202
+ <!-- if method_list -->
203
+
204
+
205
+ </div>
206
+
207
+
208
+ <div id="validator-badges">
209
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
210
+ </div>
211
+
212
+ </body>
213
+ </html>