extended_attributes 1.0.1

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/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .redcar
2
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source :rubygems
2
+ gem 'activerecord', '3.1.0'
3
+ gem 'mysql2'
4
+ gem 'rspec', '~> 2.6.0'
data/MIT-LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ == extended_attributes
2
+
3
+ Copyright (c) 2011 Chirantan Rajhans.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # Extended Attributes
2
+ _Add custom behavior to your model attributes in ActiveRecord_
3
+
4
+ How often do you have to have an instance method implemented in a model but only to work with just 1 attribute?
5
+
6
+ ```ruby
7
+ class User < ActiveRecord::Base
8
+
9
+ def first_name
10
+ name.split(' ').first
11
+ end
12
+
13
+ end
14
+ ```
15
+
16
+ But attributes are also objects at the end of the day right? Should the first_name method belong to the attribute name? With this gem you can extend your attribute by mixing modules with them or having attribute specific methods defined on them. Just like our relationship objects.
17
+
18
+ In your Gemfile
19
+
20
+ ```ruby
21
+ gem 'extended_attributes'
22
+ ```
23
+
24
+
25
+ ```bash
26
+ $ bundle install
27
+ ```
28
+
29
+ and now you can do:
30
+
31
+ ```ruby
32
+ class User < ActiveRecord::Base
33
+
34
+ extend_attribute :name do
35
+
36
+ def first
37
+ split(' ').first
38
+ end
39
+
40
+ def last
41
+ split(' ').last
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+ ```
48
+
49
+ And you will be able to do:
50
+
51
+ ```ruby
52
+ user = User.find(:first)
53
+ user.name # John Anderson
54
+ user.name.first # John
55
+ user.name.last # Anderson
56
+ ```
57
+
58
+ Additionally, you can also have modules exteded on the attributes
59
+
60
+ ```ruby
61
+ module NameMethods
62
+
63
+ def first
64
+ split(' ').first
65
+ end
66
+
67
+ def last
68
+ split(' ').last
69
+ end
70
+
71
+ end
72
+
73
+ class User < ActiveRecord::Base
74
+
75
+ extend_attribute :name, :extend => NameMethods
76
+
77
+ end
78
+ ```
79
+
80
+ ### Why?
81
+
82
+ Extending attributes adds modularity to your design, better object orientation and makes interfaces clean.
83
+
84
+ ### Dealing with Fixnum
85
+
86
+ [Fixnums cannot have singleton methods](www.ruby-forum.com/topic/50170). Thus, if you try to extend an attribute that is a Fixnum, the whole behavior will be `include`d on Fixnum class, which means that the same behavior will be available on all instances of Fixnum throughout your application. So be careful with them.
87
+
88
+ ### Note
89
+
90
+ This gem was developed because I liked it and it serves my purpose. Feel free to add to it. I’ll be happy to accept pull requests.
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup :default, :development
4
+
5
+ desc 'Default: run specs'
6
+ task :default => :spec
7
+
8
+ require 'rspec/core/rake_task'
9
+ RSpec::Core::RakeTask.new do |t|
10
+ t.pattern = "spec/**/*_spec.rb"
11
+ end
12
+
13
+ Bundler::GemHelper.install_tasks
Binary file
@@ -0,0 +1,20 @@
1
+ $:.push File.dirname(__FILE__) + '/lib'
2
+ require 'extended_attributes.rb'
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = %q{extended_attributes}
6
+ gem.authors = ["Chirantan Rajhans"]
7
+ gem.date = %q{2011-10-10}
8
+ gem.description = %q{Extend behavior of attributes of your active record models.}
9
+ gem.summary = "Objectify your active record attributes."
10
+ gem.email = %q{chirantan.rajhans@gmail.com}
11
+ gem.homepage = 'http://github.com/chirantan'
12
+
13
+ gem.add_runtime_dependency 'active_record', '< 3.1.0'
14
+
15
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ gem.files = `git ls-files`.split("\n")
17
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ gem.require_paths = ['lib']
19
+ gem.version = '1.0.1'
20
+ end
@@ -0,0 +1,37 @@
1
+ require 'active_support'
2
+ require 'active_record'
3
+
4
+ module ActiveRecord
5
+ class Base
6
+ class << self
7
+ def extend_attribute(attr, options = {}, &block)
8
+ after_initialize ExtendAttribute.new(attr, options, block)
9
+ after_find ExtendAttribute.new(attr, options, block)
10
+ end
11
+ end
12
+
13
+ class ExtendAttribute
14
+
15
+ def initialize(attr, options = {}, block = nil)
16
+ @attr = attr
17
+ @options = options
18
+ @block = block
19
+ end
20
+
21
+ def after_initialize(record)
22
+ modules = [*@options[:extend]].compact
23
+ modules << Module.new(&@block) if @block
24
+ modules.each do |mod|
25
+ attribute = record.send(@attr)
26
+ unless attribute.is_a? Fixnum
27
+ attribute.extend mod
28
+ else
29
+ Fixnum.send(:include, mod)
30
+ end
31
+ end
32
+ end
33
+ alias :after_find :after_initialize
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,8 @@
1
+ module DateMethods
2
+
3
+ def age
4
+ now = Time.now.utc.to_date
5
+ now.year - self.year - ((now.month > self.month || (now.month == self.month && now.day >= self.day)) ? 0 : 1)
6
+ end
7
+
8
+ end
@@ -0,0 +1,22 @@
1
+ require 'rubygems'
2
+ require 'active_record'
3
+ require File.expand_path(File.dirname(__FILE__) + '/user.rb')
4
+
5
+ ActiveRecord::Base.establish_connection(
6
+ :adapter => 'mysql2',
7
+ :host => 'localhost',
8
+ :username => 'root',
9
+ :password => 'admin',
10
+ :database => 'extend_attributes_test',
11
+ :socket => '/var/run/mysqld/mysqld.sock'
12
+ )
13
+
14
+ ActiveRecord::Schema.define do
15
+ drop_table :users rescue nil
16
+ create_table :users do |t|
17
+ t.string :name
18
+ t.integer :work_experience
19
+ t.date :dob
20
+ end
21
+ end
22
+
data/spec/user.rb ADDED
@@ -0,0 +1,28 @@
1
+
2
+ require File.expand_path(File.dirname(__FILE__) + '/date_methods.rb')
3
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/extended_attributes.rb')
4
+
5
+ class User < ActiveRecord::Base
6
+
7
+ extend_attribute :name do
8
+ def first
9
+ self.split(' ').first
10
+ end
11
+
12
+ def last
13
+ self.split(' ').last
14
+ end
15
+ end
16
+
17
+ extend_attribute :work_experience do
18
+
19
+ def in_months
20
+ self * 12
21
+ end
22
+
23
+ end
24
+
25
+ extend_attribute :dob, :extend => DateMethods
26
+
27
+
28
+ end
data/spec/user_spec.rb ADDED
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper.rb')
2
+
3
+ describe User do
4
+
5
+ before(:each) do
6
+ @user = User.create(
7
+ :name => 'Chirantan Rajhans',
8
+ :work_experience => 3,
9
+ :dob => Date.parse("6th February 1986")
10
+ )
11
+ end
12
+
13
+
14
+ it 'should extend name attribute with "first" and "last" methods' do
15
+ @user.name.first.should == 'Chirantan'
16
+ @user.name.last.should == 'Rajhans'
17
+ end
18
+
19
+ it 'should extend work_experience attribute with "in_months" method' do
20
+ @user.work_experience.in_months.should == 36
21
+ end
22
+
23
+ it 'should extend dob attribute with DateMethods module' do
24
+ @user.dob.age.should == 25
25
+ end
26
+
27
+ end
28
+
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: extended_attributes
3
+ version: !ruby/object:Gem::Version
4
+ hash: 21
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 1
10
+ version: 1.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Chirantan Rajhans
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-10-10 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: active_record
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - <
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 3
31
+ - 1
32
+ - 0
33
+ version: 3.1.0
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ description: Extend behavior of attributes of your active record models.
37
+ email: chirantan.rajhans@gmail.com
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - .gitignore
46
+ - Gemfile
47
+ - MIT-LICENSE
48
+ - README.md
49
+ - Rakefile
50
+ - extended_attributes-1.0.0.gem
51
+ - extended_attributes.gemspec
52
+ - lib/extended_attributes.rb
53
+ - spec/date_methods.rb
54
+ - spec/spec_helper.rb
55
+ - spec/user.rb
56
+ - spec/user_spec.rb
57
+ homepage: http://github.com/chirantan
58
+ licenses: []
59
+
60
+ post_install_message:
61
+ rdoc_options: []
62
+
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ hash: 3
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ requirements: []
84
+
85
+ rubyforge_project:
86
+ rubygems_version: 1.8.11
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Objectify your active record attributes.
90
+ test_files: []
91
+