correspondence 0.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.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use --create default@correspondence
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in correspondence.gemspec
4
+ gemspec
@@ -0,0 +1,31 @@
1
+ #Correspondence
2
+ ####Next generation associations
3
+
4
+ ##Todo
5
+ * `one` associations<br/>
6
+ Support defining a class and method to find associated object
7
+ * `many` assocations<br/>
8
+ Support defining a class and finding multiple related objects
9
+ * Arbitrary item `many` associations<br/>
10
+ Support finding N arbitrary objects related to the querying object
11
+ * Automagically inferring inverse relationships.
12
+
13
+ ##Usage
14
+ class User
15
+ corresponds_with :profile
16
+ end
17
+
18
+ This will create a `profile` method on any instance of the user class. By
19
+ default the `profile` method will call `Profile.find(id)` where `id` is a
20
+ method on the user class.
21
+
22
+ ###Options
23
+ * `:class_name` specify a string for the association class name.
24
+ * `:class` allows specifying a string, class, symbol or proc. Symbols must be
25
+ class methods on the associating class, procs should resolve to the
26
+ association class.
27
+ * `:on` a symbol or string specifying the method that should be called on the
28
+ associating class as a reference to the association. Defaults to `:id`.
29
+ * `:using` a symbol or string that is the method that will be called on the
30
+ association call. This method will be passed the results of `:on`. Defaults
31
+ to `:find`.
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "correspondence/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "correspondence"
7
+ s.version = Correspondence::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Adam Hunter", "Ben Vandgrift"]
10
+ s.email = ["adamhunter@me.com", "ben@vandgrift.com"]
11
+ s.homepage = ""
12
+ s.summary = %q[Next generation object associations.]
13
+ s.description = %q[Associate related ruby objects, like ActiveRecord assocations for arbitrary classes. Useful for polyglot programming across seperate data stores using different Object Mappers.]
14
+
15
+ s.add_dependency 'activesupport', '~> 3.0.0'
16
+ s.add_dependency 'i18n', '~> 0.5'
17
+
18
+ s.add_development_dependency 'rspec', '~> 2.5'
19
+
20
+ s.rubyforge_project = "correspondence"
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
+ s.require_paths = ["lib"]
26
+ end
@@ -0,0 +1,7 @@
1
+ require 'active_support/all'
2
+
3
+ module Correspondence
4
+ end
5
+
6
+ require 'correspondence/with'
7
+ require 'correspondence/version'
@@ -0,0 +1,3 @@
1
+ module Correspondence
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,29 @@
1
+ require 'correspondence'
2
+
3
+ module Correspondence
4
+ module With
5
+ extend ActiveSupport::Concern
6
+ extend ActiveSupport::Autoload
7
+
8
+ autoload :ManyProxy
9
+ autoload :OneProxy
10
+ autoload :Proxy
11
+
12
+ module ClassMethods
13
+ def corresponds_with(association, options={}, &block)
14
+ type = plural_association?(association) ? 'Many' : 'One'
15
+ correspondences[association.to_sym] = const_get("#{type}Proxy").new(self, association, options)
16
+ end
17
+
18
+ def correspondences
19
+ @correspondences ||= Hash.new
20
+ end
21
+
22
+ private
23
+
24
+ def plural_association?(association)
25
+ association.to_s.pluralize == association.to_s
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,10 @@
1
+ module Correspondence
2
+ module With
3
+ class ManyProxy < Proxy
4
+
5
+ protected
6
+ def create_association
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ module Correspondence
2
+ module With
3
+ class OneProxy < Proxy
4
+
5
+ protected
6
+ def create_association
7
+ root.class_eval <<-RB
8
+ def #{name}
9
+ #{@target}.#{@options[:using]}(#{@options[:on]})
10
+ end
11
+ RB
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,39 @@
1
+ module Correspondence
2
+ module With
3
+ class Proxy
4
+ attr_reader :root, :name, :target
5
+
6
+ def initialize(root, name, options)
7
+ @root = root
8
+ @name = name.to_sym
9
+ @options = options
10
+ @target = set_target
11
+ @options[:on] ||= :id
12
+ @options[:using] ||= :find
13
+ create_association
14
+ end
15
+
16
+ protected
17
+ def set_target
18
+ @options[:class] = @options[:class_name] if @options[:class_name]
19
+
20
+ if @options[:class].is_a?(Class)
21
+ @options[:class]
22
+ elsif @options[:class].is_a?(String)
23
+ @options[:class].constantize
24
+ elsif @options[:class].is_a?(Symbol)
25
+ root.send(@options[:class])
26
+ elsif @options[:class].respond_to?(:call)
27
+ @options[:class].call
28
+ else
29
+ @name.to_s.classify.constantize
30
+ end
31
+ end
32
+
33
+ def create_association
34
+ raise NotImplementedError
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ describe Correspondence::With::OneProxy do
4
+
5
+
6
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe Correspondence::With::OneProxy do
4
+ before :all do
5
+ Bar.corresponds_with :foo
6
+ end
7
+
8
+ after :all do
9
+ Bar.instance_variable_set(:@correspondences, {})
10
+ end
11
+
12
+ it "should add the associated method to the associating class" do
13
+ Bar.new.should respond_to(:foo)
14
+ end
15
+
16
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Correspondence::With::Proxy do
4
+
5
+ it "should assume the target is association name" do
6
+ proxy = TestProxy.new(Bar, :foo, {})
7
+ proxy.target.should eq(Foo)
8
+ end
9
+
10
+ it "should allow specifiying the target's class_name" do
11
+ proxy = TestProxy.new(Bar, :foo, {:class_name => 'Box'})
12
+ proxy.target.should eq(Box)
13
+ end
14
+
15
+ it "should allow specifiying the target's class" do
16
+ proxy = TestProxy.new(Bar, :foo, {:class => Foo})
17
+ proxy.target.should eq(Foo)
18
+ end
19
+
20
+ it "should allow using a string to specify the target's class" do
21
+ proxy = TestProxy.new(Bar, :foo, {:class => 'Foo'})
22
+ proxy.target.should eq(Foo)
23
+ end
24
+
25
+ it "should allow using a proc to specify the target's class" do
26
+ proxy = TestProxy.new(Bar, :foo, {:class => proc { Foo }})
27
+ proxy.target.should eq(Foo)
28
+ end
29
+
30
+ it "should allow passing a symbol to reference a method to determine the target's class" do
31
+ proxy = TestProxy.new(Bar, :foo, {:class => :foo_class_name})
32
+ proxy.target.should eq(Foo)
33
+ end
34
+
35
+ end
36
+
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Correspondence::With do
4
+
5
+ describe "creating an association" do
6
+ it "should instantiate a one association when corresponding with a singular symbol" do
7
+ Foo.corresponds_with :bar
8
+ Foo.correspondences[:bar].should be_a(Correspondence::With::OneProxy)
9
+ end
10
+
11
+ it "should instantiate a many association when corresponding with a plural symbol" do
12
+ Bar.corresponds_with :boxes
13
+ Bar.correspondences[:boxes].should be_a(Correspondence::With::ManyProxy)
14
+ end
15
+
16
+ it "should create an assocation with the associated class" do
17
+ Profile.stub!(:find).with(1).and_return(@profile = mock('Profile', :id => 1))
18
+ @user = User.new
19
+ @user.id = 1
20
+ @user.profile.should eq(@profile)
21
+ end
22
+
23
+ it "should assume the default finder method is :find"
24
+ it "should allow specifiying the :finder_method"
25
+ it "should assume the default correspondence method is :id"
26
+ it "should allow specifiying the method to use to correspond to the associated object"
27
+ end
28
+
29
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Correspondence do
4
+
5
+ it "should have a version number" do
6
+ Correspondence::VERSION.should be_a(String)
7
+ end
8
+
9
+ end
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'rubygems' # Use the gems path only for the spec suite
4
+ require 'correspondence'
5
+ require 'rspec'
6
+
7
+ Dir[File.join(File.dirname(__FILE__), "support", "*.rb")].each {|f| require f }
8
+
9
+ RSpec.configure do |config|
10
+ config.mock_with :rspec
11
+ end
12
+
@@ -0,0 +1,10 @@
1
+ class Bar
2
+ def self.foo_class_name; Foo; end
3
+ end
4
+
5
+ class Foo ; end
6
+ class Box ; end
7
+ class Baz ; end
8
+
9
+ [Foo, Bar, Box, Baz].each {|c| c.send(:include, Correspondence::With)}
10
+
@@ -0,0 +1,2 @@
1
+ class Profile
2
+ end
@@ -0,0 +1,5 @@
1
+ class TestProxy < Correspondence::With::Proxy
2
+ def create_association
3
+ "test association"
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ class User
2
+ include Correspondence::With
3
+
4
+ attr_accessor :id
5
+
6
+ corresponds_with :profile
7
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: correspondence
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Adam Hunter
14
+ - Ben Vandgrift
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-03-07 00:00:00 -05:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: activesupport
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ hash: 7
31
+ segments:
32
+ - 3
33
+ - 0
34
+ - 0
35
+ version: 3.0.0
36
+ type: :runtime
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ name: i18n
40
+ prerelease: false
41
+ requirement: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ hash: 1
47
+ segments:
48
+ - 0
49
+ - 5
50
+ version: "0.5"
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: rspec
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ hash: 9
62
+ segments:
63
+ - 2
64
+ - 5
65
+ version: "2.5"
66
+ type: :development
67
+ version_requirements: *id003
68
+ description: Associate related ruby objects, like ActiveRecord assocations for arbitrary classes. Useful for polyglot programming across seperate data stores using different Object Mappers.
69
+ email:
70
+ - adamhunter@me.com
71
+ - ben@vandgrift.com
72
+ executables: []
73
+
74
+ extensions: []
75
+
76
+ extra_rdoc_files: []
77
+
78
+ files:
79
+ - .gitignore
80
+ - .rvmrc
81
+ - Gemfile
82
+ - README.md
83
+ - Rakefile
84
+ - correspondence.gemspec
85
+ - lib/correspondence.rb
86
+ - lib/correspondence/version.rb
87
+ - lib/correspondence/with.rb
88
+ - lib/correspondence/with/many_proxy.rb
89
+ - lib/correspondence/with/one_proxy.rb
90
+ - lib/correspondence/with/proxy.rb
91
+ - spec/correspondence/with/many_proxy_spec.rb
92
+ - spec/correspondence/with/one_proxy_spec.rb
93
+ - spec/correspondence/with/proxy_spec.rb
94
+ - spec/correspondence/with_spec.rb
95
+ - spec/correspondence_spec.rb
96
+ - spec/spec_helper.rb
97
+ - spec/support/basics.rb
98
+ - spec/support/profile.rb
99
+ - spec/support/test_proxy.rb
100
+ - spec/support/user.rb
101
+ has_rdoc: true
102
+ homepage: ""
103
+ licenses: []
104
+
105
+ post_install_message:
106
+ rdoc_options: []
107
+
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ hash: 3
116
+ segments:
117
+ - 0
118
+ version: "0"
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ none: false
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ hash: 3
125
+ segments:
126
+ - 0
127
+ version: "0"
128
+ requirements: []
129
+
130
+ rubyforge_project: correspondence
131
+ rubygems_version: 1.5.2
132
+ signing_key:
133
+ specification_version: 3
134
+ summary: Next generation object associations.
135
+ test_files:
136
+ - spec/correspondence/with/many_proxy_spec.rb
137
+ - spec/correspondence/with/one_proxy_spec.rb
138
+ - spec/correspondence/with/proxy_spec.rb
139
+ - spec/correspondence/with_spec.rb
140
+ - spec/correspondence_spec.rb
141
+ - spec/spec_helper.rb
142
+ - spec/support/basics.rb
143
+ - spec/support/profile.rb
144
+ - spec/support/test_proxy.rb
145
+ - spec/support/user.rb