getter_for 0.1.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.
- data/.gitignore +2 -0
- data/LICENSE +20 -0
- data/README.textile +61 -0
- data/Rakefile +21 -0
- data/TODO.textile +5 -0
- data/VERSION +1 -0
- data/getter_for.gemspec +53 -0
- data/lib/getter_for.rb +31 -0
- data/rails/init.rb +2 -0
- data/spec/getter_for_spec.rb +142 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +12 -0
- metadata +68 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Martin Linkhorst
|
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.textile
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
h1. Getter For
|
2
|
+
|
3
|
+
<pre>
|
4
|
+
gem install getter_for
|
5
|
+
</pre>
|
6
|
+
|
7
|
+
h2. Setup
|
8
|
+
|
9
|
+
image you have a ticket model that belongs to a user. you can add convenience methods for any user attribute like that:
|
10
|
+
|
11
|
+
<pre>
|
12
|
+
class Ticket < ActiveRecord::Base
|
13
|
+
belongs_to :user
|
14
|
+
|
15
|
+
getter_for :user => :name
|
16
|
+
end
|
17
|
+
|
18
|
+
@ticket = Ticket.new
|
19
|
+
@ticket.user_name # => @ticket.user.name if @ticket.user
|
20
|
+
</pre>
|
21
|
+
|
22
|
+
That method returns nil if user is nil, so it can safely used in your views
|
23
|
+
|
24
|
+
You can pass multiple key/value pairs separated by comma and provide arrays for both model name and method name. let me show you:
|
25
|
+
|
26
|
+
<pre>
|
27
|
+
class Project < ActiveRecord::Base
|
28
|
+
belongs_to :category
|
29
|
+
belongs_to :user
|
30
|
+
belongs_to :assignee, :class_name => 'User'
|
31
|
+
|
32
|
+
getter_for [:category, :user] => :name,
|
33
|
+
:assignee => [:email, :phone]
|
34
|
+
end
|
35
|
+
|
36
|
+
@project = Project.new
|
37
|
+
@project.category_name # => @project.category.name if @project.category
|
38
|
+
@project.user_name # => @project.user.name if @project.user
|
39
|
+
@project.assignee_email # => @project.assignee.email if @project.assignee
|
40
|
+
@project.assignee_phone # => @project.assignee.phone if @project.assignee
|
41
|
+
</pre>
|
42
|
+
|
43
|
+
you can also make fancy stuff like:
|
44
|
+
|
45
|
+
<pre>
|
46
|
+
class User < ActiveRecord::Base
|
47
|
+
belongs_to :department
|
48
|
+
getter_for :department => :name # => user.department_name
|
49
|
+
end
|
50
|
+
|
51
|
+
class Comment < ActiveRecord::Base
|
52
|
+
belongs_to :user
|
53
|
+
getter_for :user => :department_name # => comment.user_department_name
|
54
|
+
end
|
55
|
+
|
56
|
+
@comment = Comment.new
|
57
|
+
@comment.user_department_name # => @comment.user.department.name if @comment.user && @comment.user.department
|
58
|
+
</pre>
|
59
|
+
|
60
|
+
|
61
|
+
Copyright (c) 2009 Martin Linkhorst, released under the MIT license.
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'spec/rake/spectask'
|
4
|
+
|
5
|
+
Spec::Rake::SpecTask.new(:spec)
|
6
|
+
task :default => :spec
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'jeweler'
|
10
|
+
Jeweler::Tasks.new do |gemspec|
|
11
|
+
gemspec.name = "getter_for"
|
12
|
+
gemspec.summary = "Adds getter methods for attributes that the object belongs to"
|
13
|
+
gemspec.description = "Generates convenience methods especially for use in views like [ticket.user_name] instead of [ticket.user.name if ticket.user]"
|
14
|
+
gemspec.email = "m.linkhorst@googlemail.com"
|
15
|
+
gemspec.homepage = "http://github.com/linki/getter_for"
|
16
|
+
gemspec.authors = ["Martin Linkhorst"]
|
17
|
+
end
|
18
|
+
Jeweler::GemcutterTasks.new
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler not available. Install it with: sudo gem install jeweler"
|
21
|
+
end
|
data/TODO.textile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/getter_for.gemspec
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{getter_for}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Martin Linkhorst"]
|
12
|
+
s.date = %q{2009-12-12}
|
13
|
+
s.description = %q{Generates convenience methods especially for use in views like [ticket.user_name] instead of [ticket.user.name if ticket.user]}
|
14
|
+
s.email = %q{m.linkhorst@googlemail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.textile"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".gitignore",
|
21
|
+
"LICENSE",
|
22
|
+
"README.textile",
|
23
|
+
"Rakefile",
|
24
|
+
"TODO.textile",
|
25
|
+
"VERSION",
|
26
|
+
"getter_for.gemspec",
|
27
|
+
"lib/getter_for.rb",
|
28
|
+
"rails/init.rb",
|
29
|
+
"spec/getter_for_spec.rb",
|
30
|
+
"spec/spec.opts",
|
31
|
+
"spec/spec_helper.rb"
|
32
|
+
]
|
33
|
+
s.homepage = %q{http://github.com/linki/getter_for}
|
34
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
s.rubygems_version = %q{1.3.5}
|
37
|
+
s.summary = %q{Adds getter methods for attributes that the object belongs to}
|
38
|
+
s.test_files = [
|
39
|
+
"spec/getter_for_spec.rb",
|
40
|
+
"spec/spec_helper.rb"
|
41
|
+
]
|
42
|
+
|
43
|
+
if s.respond_to? :specification_version then
|
44
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
45
|
+
s.specification_version = 3
|
46
|
+
|
47
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
48
|
+
else
|
49
|
+
end
|
50
|
+
else
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
data/lib/getter_for.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module GetterFor
|
2
|
+
def self.included(base)
|
3
|
+
base.extend(ClassMethods)
|
4
|
+
end
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def getter_for(arguments)
|
8
|
+
raise ArgumentError unless arguments.kind_of?(Hash)
|
9
|
+
|
10
|
+
arguments.each do |models, methods|
|
11
|
+
[models, methods].each do |attributes|
|
12
|
+
raise ArgumentError unless [Array, Symbol, String].inject(false) { |bool, klass| bool || attributes.kind_of?(klass) }
|
13
|
+
attributes.kind_of?(Array) && attributes.each do |attribute|
|
14
|
+
raise ArgumentError unless [Symbol, String].inject(false) { |bool, klass| bool || attribute.kind_of?(klass) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
models = [models] unless models.kind_of?(Array)
|
19
|
+
methods = [methods] unless methods.kind_of?(Array)
|
20
|
+
|
21
|
+
models.each do |model|
|
22
|
+
methods.each do |method|
|
23
|
+
define_method "#{model}_#{method}" do
|
24
|
+
send(model).send(method) if send(model)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "/spec_helper")
|
2
|
+
|
3
|
+
describe GetterFor do
|
4
|
+
describe "getter" do
|
5
|
+
class Ticket
|
6
|
+
include GetterFor
|
7
|
+
getter_for :user => :name
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should respond to :user_name" do
|
11
|
+
ticket = Ticket.new
|
12
|
+
ticket.should respond_to(:user_name)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return the user's name" do
|
16
|
+
ticket, user = [Ticket, Object].map(&:new)
|
17
|
+
user.expects(:name).returns('Han Solo')
|
18
|
+
ticket.expects(:user).twice.returns(user)
|
19
|
+
ticket.user_name.should == 'Han Solo'
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should return nil if user is nil" do
|
23
|
+
ticket = Ticket.new
|
24
|
+
ticket.expects(:user).returns(nil)
|
25
|
+
ticket.user_name.should == nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should raise an error if user does not respond to :name" do
|
29
|
+
ticket, user = [Ticket, Object].map(&:new)
|
30
|
+
ticket.expects(:user).twice.returns(user)
|
31
|
+
lambda {
|
32
|
+
ticket.user_name
|
33
|
+
}.should raise_error(NoMethodError)
|
34
|
+
end
|
35
|
+
|
36
|
+
class Product
|
37
|
+
include GetterFor
|
38
|
+
getter_for 'manufactory' => 'name'
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should accept strings" do
|
42
|
+
product, manufactory = [Product, Object].map(&:new)
|
43
|
+
manufactory.expects(:name).returns('Death Star')
|
44
|
+
product.expects(:manufactory).twice.returns(manufactory)
|
45
|
+
product.manufactory_name.should == 'Death Star'
|
46
|
+
end
|
47
|
+
|
48
|
+
class Issue
|
49
|
+
include GetterFor
|
50
|
+
getter_for :user => :name, :assignee => :email
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should take multiple arguments" do
|
54
|
+
issue = Issue.new
|
55
|
+
issue.should respond_to(:user_name)
|
56
|
+
issue.should respond_to(:assignee_email)
|
57
|
+
end
|
58
|
+
|
59
|
+
class Package
|
60
|
+
include GetterFor
|
61
|
+
getter_for :carrier => [:name, :email]
|
62
|
+
getter_for [:category, :sender] => :name
|
63
|
+
getter_for [:location, :destination] => [:name, :description]
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should accept collection of keys and values" do
|
67
|
+
package = Package.new
|
68
|
+
[:carrier_name, :carrier_email, :category_name, :sender_name,
|
69
|
+
:location_name, :location_description, :destination_name, :destination_description].each do |attribute|
|
70
|
+
package.should respond_to(attribute)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class Fancy
|
75
|
+
include GetterFor
|
76
|
+
getter_for :user => :name, :user_name => :downcase
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should work fancy" do
|
80
|
+
fancy, name = [Fancy, Object].map(&:new)
|
81
|
+
name.expects(:downcase).returns('han solo')
|
82
|
+
fancy.expects(:user_name).twice.returns(name)
|
83
|
+
fancy.user_name_downcase.should == 'han solo'
|
84
|
+
end
|
85
|
+
|
86
|
+
class User
|
87
|
+
include GetterFor
|
88
|
+
getter_for :department => :name
|
89
|
+
end
|
90
|
+
|
91
|
+
class Comment
|
92
|
+
include GetterFor
|
93
|
+
getter_for :user => :department_name
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should work nested" do
|
97
|
+
comment, user, department = [Comment, User, Object].map(&:new)
|
98
|
+
department.expects(:name).returns('Development')
|
99
|
+
user.expects(:department).twice.returns(department)
|
100
|
+
comment.expects(:user).twice.returns(user)
|
101
|
+
comment.user_department_name.should == 'Development'
|
102
|
+
end
|
103
|
+
|
104
|
+
class Model
|
105
|
+
include GetterFor
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should respond to :getter_for" do
|
109
|
+
Model.should respond_to(:getter_for)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should require a parameter" do
|
113
|
+
lambda { Model.send :getter_for }.should raise_error(ArgumentError)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should require a hash" do
|
117
|
+
lambda { Model.send :getter_for, [] }.should raise_error(ArgumentError)
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should have either a symbol or string or an array of symbols or strings as key" do
|
121
|
+
lambda { Model.send :getter_for, { :attr => :attr } }.should_not raise_error(ArgumentError)
|
122
|
+
lambda { Model.send :getter_for, { 'attr' => :attr } }.should_not raise_error(ArgumentError)
|
123
|
+
lambda { Model.send :getter_for, { [:user, 'category'] => :attr } }.should_not raise_error(ArgumentError)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should raise an error if key is not a symbol, string or array of symbols or strings" do
|
127
|
+
lambda { Model.send :getter_for, { 1 => :attr } }.should raise_error(ArgumentError)
|
128
|
+
lambda { Model.send :getter_for, { [:attr, 2] => :attr } }.should raise_error(ArgumentError)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should have either a symbol or string or an array of symbols or strings as value" do
|
132
|
+
lambda { Model.send :getter_for, { :attr => 'attr' } }.should_not raise_error(ArgumentError)
|
133
|
+
lambda { Model.send :getter_for, { :attr => :attr } }.should_not raise_error(ArgumentError)
|
134
|
+
lambda { Model.send :getter_for, { :attr => [:name, 'synomym'] } }.should_not raise_error(ArgumentError)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should raise an error if value is not a symbol, string or array of symbols or strings" do
|
138
|
+
lambda { Model.send :getter_for, { :attr => 1 } }.should raise_error(ArgumentError)
|
139
|
+
lambda { Model.send :getter_for, { :attr => [:attr, 2] } }.should raise_error(ArgumentError)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: getter_for
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Martin Linkhorst
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-12 00:00:00 +10:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Generates convenience methods especially for use in views like [ticket.user_name] instead of [ticket.user.name if ticket.user]
|
17
|
+
email: m.linkhorst@googlemail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
- README.textile
|
25
|
+
files:
|
26
|
+
- .gitignore
|
27
|
+
- LICENSE
|
28
|
+
- README.textile
|
29
|
+
- Rakefile
|
30
|
+
- TODO.textile
|
31
|
+
- VERSION
|
32
|
+
- getter_for.gemspec
|
33
|
+
- lib/getter_for.rb
|
34
|
+
- rails/init.rb
|
35
|
+
- spec/getter_for_spec.rb
|
36
|
+
- spec/spec.opts
|
37
|
+
- spec/spec_helper.rb
|
38
|
+
has_rdoc: true
|
39
|
+
homepage: http://github.com/linki/getter_for
|
40
|
+
licenses: []
|
41
|
+
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options:
|
44
|
+
- --charset=UTF-8
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.3.5
|
63
|
+
signing_key:
|
64
|
+
specification_version: 3
|
65
|
+
summary: Adds getter methods for attributes that the object belongs to
|
66
|
+
test_files:
|
67
|
+
- spec/getter_for_spec.rb
|
68
|
+
- spec/spec_helper.rb
|