dynattribs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ .DS_Store
2
+ log/*
3
+ tmp/**/*
4
+ bin/*
5
+ *.log
6
+ *~
7
+ .project
8
+ .loadpath
9
+ ._*
10
+ .bundle
11
+ *.gem
12
+ *.swp
13
+ Gemfile.lock
14
+ .rvmrc
15
+ .redcar/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in dynattribs.gemspec
4
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2013 James P. McGrath
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.rdoc ADDED
@@ -0,0 +1,81 @@
1
+ = Dynattribs (Dynamic Attributes)
2
+ Dynattribs makes it easy to declare dynamic attributes in ActiveRecord classes.
3
+
4
+ == Overview
5
+
6
+ The Dynattribs Gem (Dyanmic Attributes) provide a database backed attributes to
7
+ ActiveRecord::Base classes, without having to declare table columns for each
8
+ attribute. A bit of NoSQL data flexibility for traditional database backed
9
+ ActiveRecord classes.
10
+
11
+ The dynamic attributes are stored as a JSON encoded Hash, and can be
12
+ persisted into any field that can store text data.
13
+
14
+ == Installation
15
+
16
+ You can use the Dynattribs in your Rails project by including the following in your Gemfile:
17
+
18
+ gem 'dynattribs'
19
+
20
+ == Usage
21
+
22
+ To use Dynattribs you need to include the mixin in your class definition, preferably at the top.
23
+
24
+ To define the names of the dynamic attributes use the "dynamic_attr_accessor"
25
+ method. This method takes two of more arguments. The first argument is the name
26
+ of the database field that the dynamic attributes will be persisted to. The other
27
+ arguments are the names of the dynamic attributes. It is meant to be used in a
28
+ similar way to the familure "attr_accessor" method
29
+
30
+
31
+ === Example
32
+ The following example defines a dynamic "info" field for the MyClass class, with
33
+ the new info field's data being persisted to the "extra_data" database field.
34
+
35
+ class MyClass < < ActiveRecord::Base
36
+ include Dynattribs
37
+
38
+ dynamic_attr_accessor :extra_data, :info
39
+ end
40
+
41
+ === Database
42
+ The dynamic attributes are stored converted to a JSON encoded string before storing
43
+ to the nominated database field. Therefore, you will need to add a string column
44
+ to the table of any class you wish to add dynamic attributes too.
45
+
46
+ A String field would work, but a "text" field would be best due to the large amount
47
+ of data that could be stored in the dynamic attributes.
48
+
49
+ To add the new column, create a migration, e.g.
50
+
51
+ rails g migration add_model_dynamic_attribute
52
+
53
+ And modify the migration to look something like this:
54
+
55
+ class AddModelDynamicAttribute < ActiveRecord::Migration
56
+ def change
57
+ add_column :models, :dynamic_attribs, :text
58
+ end
59
+ end
60
+
61
+ == In The Wild
62
+
63
+ Dynattribs is used in a number of production systems:
64
+
65
+ {Capstory - Private Group Photo Albums }[http://www.capstory.com/]
66
+
67
+ {Authic - A Local shopping Sales Notification Service}[http://www.authic.com]
68
+
69
+ If you are using Dynattribs in your project and would like to be added to this list, please get in touch!
70
+
71
+ == Contributing
72
+
73
+ Contributions are very welcome. Please ensure all pull requests include suitable test coverage and all tests are passing.
74
+
75
+ == Authors
76
+
77
+ * {James McGrath}[https://github.com/jpmcgrath]
78
+
79
+ == Licence
80
+
81
+ This code is licensed under the MIT license. See MIT-LICENCE for more details.
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+ require 'rdoc/task'
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ task :default => :spec
7
+ RSpec::Core::RakeTask.new
8
+
9
+ RDoc::Task.new :rdoc do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Dynattribs'
12
+ rdoc.options << '--line-numbers' << '--inline-source'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path("../lib/dynattribs/version", __FILE__)
2
+
3
+ # Provide a simple gemspec so you can easily use your enginex
4
+ # project in your rails apps through git.
5
+ Gem::Specification.new do |s|
6
+ s.name = "dynattribs"
7
+ s.summary = "Dynattribs makes it easy to declare dynamic attributes in ActiveRecord classes."
8
+ s.description = "The Dynattribs Gem (Dyanmic Attributes) provide a database backed attributes to ActiveRecord::Base classes, without having to declare table columns for each attribute. A bit of NoSQL data flexibility for traditional database backed ActiveRecord classes."
9
+ s.files = `git ls-files`.split("\n")
10
+ s.version = Dynattribs::VERSION
11
+ s.platform = Gem::Platform::RUBY
12
+ s.authors = [ "James P. McGrath" ]
13
+ s.email = [ "gems@jamespmcgrath.com" ]
14
+ s.homepage = "http://jamespmcgrath.com/projects/dynattribs"
15
+ s.rubyforge_project = "dynattribs"
16
+ s.required_rubygems_version = "> 1.3.6"
17
+ #s.add_dependency "rails", ">= 3.0.7"
18
+ s.add_development_dependency "rspec"
19
+ s.add_development_dependency "sqlite3"
20
+ s.add_development_dependency "activerecord"
21
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
22
+ s.require_path = 'lib'
23
+ end
data/lib/dynattribs.rb ADDED
@@ -0,0 +1,83 @@
1
+ module Dynattribs
2
+
3
+ ############################################################
4
+ #
5
+ # PARSE AND ENCODE THE DYNAMIC FIELD DATA
6
+ # the data is stored to a field defined by "dynamic_attributes_backing_field_name"
7
+ #
8
+ ############################################################
9
+
10
+ # parse and return the json encoded values from the encoded
11
+ # data stored in the nominated attribute
12
+ def mapped_data
13
+ return {} if self[dynamic_attributes_backing_field_name].nil?
14
+ JSON.parse(self[dynamic_attributes_backing_field_name])
15
+ end
16
+
17
+ # JSON encode and store a hash of attributes
18
+ def mapped_data=hash
19
+ self[dynamic_attributes_backing_field_name] = hash.to_json
20
+ end
21
+
22
+ ############################################################
23
+ #
24
+ # GENERAL GET/SET METHODS
25
+ #
26
+ ############################################################
27
+
28
+ # a general method for retieving a named attribute
29
+ # from the encoded data
30
+ def get_dynamic_attr(attr_name)
31
+ mapped_data[attr_name]
32
+ end
33
+
34
+ # a general method to set the value of the named
35
+ # attribute in the data map
36
+ def set_dynamic_attr(attr_name, value)
37
+ data_map = self.mapped_data
38
+ data_map[attr_name] = value
39
+ self.mapped_data = data_map
40
+ end
41
+
42
+ ############################################################
43
+ #
44
+ # CLASS METHODS
45
+ #
46
+ ############################################################
47
+
48
+ # this bit of ma allows us to "include" class methods (instead of
49
+ # the normal "extend")with the mixin.
50
+ # which is needed as the dynamic_attr_accessor method needs
51
+ # to be invoked as a class method as it is used in the class
52
+ # definition, rather than from within a instance method
53
+ def self.included(base)
54
+ base.extend(ClassMethods)
55
+ end
56
+
57
+ module ClassMethods
58
+
59
+ # takes two or more arguments, first arg is the name of the database
60
+ # field that backs the dynamic fields data hash.
61
+ # the other arguments are used to create getter/setter methods of
62
+ # the arguments name.
63
+ def dynamic_attr_accessor(*args)
64
+
65
+ # the first element in the array is the name of the field
66
+ # used to store the json encoded dynamic attribute data
67
+ dynamic_attributes_backing_field_name = args.shift
68
+ # create a method to access this extra data field name
69
+ self.class_eval("def dynamic_attributes_backing_field_name;'#{dynamic_attributes_backing_field_name}';end") if !dynamic_attributes_backing_field_name.empty?
70
+
71
+ # iterate through the rest of the arguments and create
72
+ # a getter and setter method of each of the desired dynamic attributes
73
+ args.each do |arg|
74
+ # getter - creates a wrapper for the get_dynamic_attr method
75
+ self.class_eval("def #{arg};get_dynamic_attr('#{arg}');end")
76
+
77
+ # setter - creates a wrapper for the set_dynamic_attr method
78
+ self.class_eval("def #{arg}=(val);set_dynamic_attr('#{arg}', val); end")
79
+ end
80
+ end
81
+ end
82
+
83
+ end
@@ -0,0 +1,3 @@
1
+ module Dynattribs
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ class CreateMyTestClass < ActiveRecord::Migration
2
+ def change
3
+ create_table(:my_test_classes) do |t|
4
+ ## Database authenticatable
5
+ t.string :email
6
+ t.text :dynamic_attribs
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ require 'support/active_record'
2
+
3
+ class MyTestClass < ActiveRecord::Base
4
+ include Dynattribs
5
+
6
+ dynamic_attr_accessor :dynamic_attribs, :info, :is_bool, :age, :tested_at
7
+
8
+ end
@@ -0,0 +1,25 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Dynattribs do
5
+
6
+ it "should store and load dynamic attributes" do
7
+ my_test_class = MyTestClass.new
8
+
9
+ my_test_class.info = "This will be stored into info"
10
+ my_test_class.is_bool = false
11
+ my_test_class.age = 24
12
+ my_test_class.tested_at = Time.now
13
+
14
+ my_test_class.save.should == true
15
+
16
+ loaded_object = MyTestClass.find(my_test_class.id)
17
+
18
+ loaded_object.nil?.should == false
19
+
20
+ loaded_object.info.should == my_test_class.info
21
+ loaded_object.is_bool.should == my_test_class.is_bool
22
+ loaded_object.age.should == my_test_class.age
23
+ loaded_object.tested_at.should == my_test_class.tested_at
24
+ end
25
+ end
@@ -0,0 +1,8 @@
1
+ # Configure Rails Envinronment
2
+ ENV["RAILS_ENV"] = "test"
3
+
4
+ require 'dynattribs'
5
+ require File.expand_path("../dummy/my_test_class.rb", __FILE__)
6
+
7
+ # Run any available migration
8
+ ActiveRecord::Migrator.migrate File.expand_path("../dummy/db/migrate/", __FILE__)
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'active_record'
3
+ ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
data/travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - rbx-18mode
7
+ - rbx-19mode
8
+ # - jruby-18mode # JRuby in 1.8 mode # jruby does not build native extensions like the sqlite gem
9
+ # - jruby-19mode # JRuby in 1.9 mode
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dynattribs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - James P. McGrath
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: sqlite3
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: activerecord
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: The Dynattribs Gem (Dyanmic Attributes) provide a database backed attributes
63
+ to ActiveRecord::Base classes, without having to declare table columns for each
64
+ attribute. A bit of NoSQL data flexibility for traditional database backed ActiveRecord
65
+ classes.
66
+ email:
67
+ - gems@jamespmcgrath.com
68
+ executables: []
69
+ extensions: []
70
+ extra_rdoc_files: []
71
+ files:
72
+ - .gitignore
73
+ - Gemfile
74
+ - MIT-LICENSE
75
+ - README.rdoc
76
+ - Rakefile
77
+ - dynattribs.gemspec
78
+ - lib/dynattribs.rb
79
+ - lib/dynattribs/version.rb
80
+ - spec/dummy/db/migrate/00001_create_my_test_class.rb
81
+ - spec/dummy/my_test_class.rb
82
+ - spec/dynattribs_spec.rb
83
+ - spec/spec_helper.rb
84
+ - spec/support/active_record.rb
85
+ - travis.yml
86
+ homepage: http://jamespmcgrath.com/projects/dynattribs
87
+ licenses: []
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>'
102
+ - !ruby/object:Gem::Version
103
+ version: 1.3.6
104
+ requirements: []
105
+ rubyforge_project: dynattribs
106
+ rubygems_version: 1.8.24
107
+ signing_key:
108
+ specification_version: 3
109
+ summary: Dynattribs makes it easy to declare dynamic attributes in ActiveRecord classes.
110
+ test_files: []