simple_eav 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use --create ruby-1.9.2-p180@simple_eav
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2011 Tim Linquist
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,75 @@
1
+ = simple_eav
2
+
3
+ simple_eav provides a more simple alternative to {acts_as_eav_model}[https://github.com/visfleet/acts_as_eav_model] that works with
4
+ ActiveRecord without any monkey patching. This gem is designed to be a replacement for acts_as_eav_model.
5
+
6
+ Acts_as_eav_model's purpose is to provide a model with any number of custom attributes. This project has the same purpose. The difference being maintaining utmost
7
+ compatibility with ActiveRecord::Base. For this reason, there is one glaring inconsistency between this gem and acts_as_eav_model.
8
+ Acts_as_eav_model overrides attributes (among other functionality) to allow you to set any custom attributes. Simple eav does not. I ommitted this in the interest
9
+ of not having to monkey patch ActiveRecord.
10
+
11
+ === Example
12
+ person = Person.new {:custom_attribute=>'value'} #This does not work in simple_eav
13
+
14
+ person = Person.new {:simple_eav_attributes => {:custom_attribute=>'value'} #This does work in simple_eav
15
+ person.custom_attribute ~> 'value'
16
+
17
+ The latter works because all simple_eav does is use ActiveRecord's built in serialize mechanism to store a hash of custom attributes.
18
+ So in this example, simple_eav_attributes is a text column in the database for the persons table. Simple eav then takes of
19
+ serializing the data for this column and defines setters/getters for your custom values.
20
+
21
+ This is the only known inconsistency between these two gems. If this is an issue in your project please let me know.
22
+
23
+ == Installation
24
+ gem install simple_eav
25
+
26
+ == Usage
27
+ === 1. Create the migration for your model
28
+
29
+ create_table :people do |t|
30
+ t.text :custom_attributes # Name this column whatever you like just *make sure* it is a TEXT field
31
+ ....
32
+ end
33
+
34
+ === 2. Configure simple_eav in your model
35
+
36
+ class Person < ActiveRecord::Base
37
+ include SimpleEav
38
+
39
+ configure_simple_eav :custom_attributes # This sets up the serialization for your custom attributes
40
+ end
41
+
42
+ === 3. Set and Get custom attributes as if they were a normal attribute on your model
43
+ person = Person.new
44
+ person.name = 'Joe'
45
+ person.name ~> 'Joe'
46
+
47
+ == Migrating to simple_eav
48
+ I have not done this yet but will hopefully be making the transition soon. I'll update the README once that's complete or let me know what you find if you migrate your project first.
49
+ At the moment, a migration would be needed that:
50
+ - Moves each attribute record to a key => value pair for the simple_eav_column on the model using acts_as_eav_model
51
+ - Destroys each attribute record
52
+
53
+ You'd also need to review where your models using acts_as_eav_model are initialized. If they depended on the single incompatibility mentioned above those calls will need to be updated.
54
+
55
+ == Contributing
56
+
57
+ * Fork the project.
58
+ * Make your feature addition or bug fix.
59
+ * Add tests for it. This is important so I don't break it in a
60
+ future version unintentionally.
61
+ * Commit, do not mess with rakefile, version, or history.
62
+ (if you want to have your own version, that is fine but bump version in a
63
+ commit by itself I can ignore when I pull)
64
+ * Send me a pull request. Bonus points for topic branches.
65
+
66
+
67
+ == Author
68
+
69
+ {Tim Linquist}[http://github.com/timo3377]
70
+
71
+ == Copyright
72
+
73
+ Copyright (c) 2011 {Tim Linquist}[http://github.com/timo3377]
74
+
75
+ See {LICENSE}[http://github.com/timo3377/simple_eav] for details.
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,45 @@
1
+ module SimpleEav
2
+ module ClassMethods
3
+ def configure_simple_eav(column)
4
+ @@column = column.to_sym
5
+ serialize @@column
6
+ end
7
+
8
+ def simple_eav_column
9
+ @@column if defined? @@column
10
+ end
11
+ end
12
+
13
+ def self.included(base)
14
+ base.extend ClassMethods
15
+ end
16
+
17
+ def simple_eav_column
18
+ self.class.simple_eav_column
19
+ end
20
+
21
+ def simple_eav_attributes
22
+ self.send(simple_eav_column.to_sym) || {}
23
+ end
24
+
25
+ def simple_eav_attributes=(attributes={})
26
+ self.send("#{simple_eav_column}=", attributes)
27
+ end
28
+
29
+ def respond_to?(method, include_private=false)
30
+ super || simple_eav_attributes.has_key?(method)
31
+ end
32
+
33
+ def method_missing(method, *args, &block)
34
+ if method.to_s =~ /=$/
35
+ _attributes = self.simple_eav_attributes
36
+ setter = method.to_s.gsub(/=/, '')
37
+ _attributes[setter.to_sym] = args.shift
38
+ self.simple_eav_attributes = _attributes
39
+ elsif simple_eav_attributes.has_key?(method.to_sym)
40
+ simple_eav_attributes[method.to_sym]
41
+ else
42
+ super(method, *args, &block)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ module SimpleEav
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "simple_eav"
7
+ s.version = SimpleEav::VERSION
8
+ s.authors = ["Tim Linquist"]
9
+ s.email = ["tim.linquist@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{A simple alternative to acts_as_eav_model.}
12
+ s.description = %q{A simple alternative to acts_as_eav_model that works with ActiveRecord without any monkey patching needed. Acts_as_eav_model's gives a model the ability to have any number of custom attributes. This project has the same goal. The difference being maintaining utmost compatability with ActiveRecord::Base.}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.extra_rdoc_files = [ "README.rdoc" ]
18
+ s.require_path = "lib"
19
+
20
+ s.add_dependency 'activerecord', '~> 3.0.7'
21
+ if RUBY_VERSION < '1.9'
22
+ s.add_development_dependency 'ruby-debug'
23
+ else
24
+ s.add_development_dependency 'ruby-debug19'
25
+ end
26
+ s.add_development_dependency 'sqlite3', '~> 1.3.3'
27
+ s.add_development_dependency 'rspec', '~> 2.6.0'
28
+ end
@@ -0,0 +1,10 @@
1
+ require 'active_record'
2
+
3
+ ActiveRecord::Schema.define do
4
+ create_table 'people', :force => true do |t|
5
+ t.string 'age'
6
+ t.text 'simple_attributes'
7
+ t.datetime 'created_at'
8
+ t.datetime 'updated_at'
9
+ end
10
+ end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleEav do
4
+ describe "Configuring a model" do
5
+ it "with the column to serialize" do
6
+ Person.simple_eav_column.should eql(:simple_attributes)
7
+ end
8
+
9
+ it "serializes the configured column" do
10
+ p= Person.create({:simple_attributes => {:name=>'John'}})
11
+ p.simple_attributes[:name].should eql('John')
12
+ end
13
+ end
14
+
15
+ describe "Expected ActiveRecord behavior" do
16
+ it "set all of the attributes" do
17
+ person = Person.create!({
18
+ :age=>'John Johnson',
19
+ :simple_attributes=>{
20
+ :name=>'John'
21
+ }
22
+ })
23
+ person.age.should eql('John Johnson')
24
+ person.name.should eql('John')
25
+ end
26
+ it "serialize and deserialize the simple_eav attributes" do
27
+ person = Person.new({:simple_attributes=>{
28
+ :name=>'John'
29
+ }})
30
+ person.save!
31
+ person.reload
32
+ person.name.should eql('John')
33
+ end
34
+ end
35
+
36
+ describe "A missing attribute" do
37
+ before( :each ) do
38
+ @person = Person.new
39
+ end
40
+ describe "when reading" do
41
+ it "raises a NoMethodError" do
42
+ lambda{ @person.unknown_eav }.should raise_error(NoMethodError)
43
+ end
44
+ end
45
+ describe "when writing" do
46
+ it "always defines the attribute without an error" do
47
+ lambda{ @person.unknown_eav = 'Simple' }.should_not raise_error
48
+ end
49
+ end
50
+ end
51
+
52
+ describe "A custom attribute" do
53
+ describe "John is a Person" do
54
+ before( :each ) do
55
+ @person = Person.new
56
+ end
57
+ it "who knows his name" do
58
+ @person.name = 'John'
59
+ @person.name.should eql('John')
60
+ end
61
+
62
+ it "who can change his name" do
63
+ @person.name = 'John'
64
+ @person.name = 'Joe'
65
+ @person.name.should eql('Joe')
66
+ end
67
+
68
+ it "who responds to his name" do
69
+ @person.name = 'John'
70
+ @person.respond_to?(:name).should be_true
71
+ end
72
+
73
+ it "who doesn't respond to someone else's name" do
74
+ @person.respond_to?(:someone_elses_name).should be_false
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ Bundler.setup
5
+ require 'rspec'
6
+
7
+ require 'active_record'
8
+ require 'sqlite3'
9
+ require 'logger'
10
+
11
+ ActiveRecord::Base.establish_connection({
12
+ :adapter => 'sqlite3',
13
+ :database => ":memory:"
14
+ })
15
+ load('db/schema.rb')
16
+
17
+ $:.push File.expand_path("../lib", __FILE__)
18
+ require 'support/person'
19
+
20
+ RSpec.configure do |config|
21
+ config.mock_with :rspec
22
+ end
23
+
24
+
@@ -0,0 +1,8 @@
1
+ require 'active_record'
2
+ require 'simple_eav'
3
+
4
+ class Person < ActiveRecord::Base
5
+ include SimpleEav
6
+
7
+ configure_simple_eav :simple_attributes
8
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_eav
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Tim Linquist
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-06-04 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activerecord
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 3.0.7
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: ruby-debug19
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :development
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: sqlite3
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.3.3
46
+ type: :development
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: 2.6.0
57
+ type: :development
58
+ version_requirements: *id004
59
+ description: A simple alternative to acts_as_eav_model that works with ActiveRecord without any monkey patching needed. Acts_as_eav_model's gives a model the ability to have any number of custom attributes. This project has the same goal. The difference being maintaining utmost compatability with ActiveRecord::Base.
60
+ email:
61
+ - tim.linquist@gmail.com
62
+ executables: []
63
+
64
+ extensions: []
65
+
66
+ extra_rdoc_files:
67
+ - README.rdoc
68
+ files:
69
+ - .gitignore
70
+ - .rvmrc
71
+ - Gemfile
72
+ - LICENSE
73
+ - README.rdoc
74
+ - Rakefile
75
+ - lib/simple_eav.rb
76
+ - lib/version.rb
77
+ - simple_eav.gemspec
78
+ - spec/db/schema.rb
79
+ - spec/lib/simple_eav_spec.rb
80
+ - spec/spec_helper.rb
81
+ - spec/support/person.rb
82
+ homepage: ""
83
+ licenses: []
84
+
85
+ post_install_message:
86
+ rdoc_options: []
87
+
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: "0"
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: "0"
102
+ requirements: []
103
+
104
+ rubyforge_project:
105
+ rubygems_version: 1.8.3
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: A simple alternative to acts_as_eav_model.
109
+ test_files:
110
+ - spec/db/schema.rb
111
+ - spec/lib/simple_eav_spec.rb
112
+ - spec/spec_helper.rb
113
+ - spec/support/person.rb