st-elsewhere 0.1.4 → 0.1.5
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/README.rdoc +14 -5
- data/Rakefile +2 -3
- data/VERSION +1 -1
- data/changelog.rdoc +9 -0
- data/lib/st-elsewhere.rb +2 -4
- data/st-elsewhere.gemspec +6 -2
- data/test/st-elsewhere_test.rb +62 -5
- data/test/test_helper.rb +7 -2
- metadata +14 -4
data/README.rdoc
CHANGED
@@ -10,11 +10,11 @@ For a variety of reasons, you might find yourself supporting multiple databases
|
|
10
10
|
|
11
11
|
=== The Problem
|
12
12
|
|
13
|
-
While there may be great benefits to connecting to multiple databases in your app, there are also costs. One example is that <b><tt>has_many :children, :through => parent_children</tt></b>
|
13
|
+
While there may be great benefits to connecting to multiple databases in your app, there are also costs. One example is that <b><tt>has_many :children, :through => parent_children</tt></b> may not work.
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
If your database connections are available on the same host {you can prefix your ActiveRecord table names with the database name}[http://gist.github.com/239853].
|
16
|
+
|
17
|
+
If your database connections are on two different hosts, no JOINs can save you and you'll need to implement your relationships in code.
|
18
18
|
|
19
19
|
=== The Solution
|
20
20
|
|
@@ -52,4 +52,13 @@ http://emphaticsolutions.com/images/has_many_elsewhere.png
|
|
52
52
|
<tt>has_many_elsewhere</tt> is certainly much less efficient than a comparable has_many relationship. <tt>has_many :through</tt> relationships use SQL JOINs which while efficient, do not work across multiple database connections. St. Elsewhere implements much of the same resulting API methods in code, using less efficient SQL.
|
53
53
|
|
54
54
|
=== Install from gemcutter
|
55
|
-
|
55
|
+
|
56
|
+
gem install st-elsewhere
|
57
|
+
|
58
|
+
=== Roadmap
|
59
|
+
|
60
|
+
Currently st-elsewhere is implemented as a basic ruby module that implements some of the basic functionality of has_many :through relationships in ActiveRecord. A much more robust implementation would be to create an ActiveRecord association proxy, like HasManyThroughAssociation, that emulates the same API and could be integrated into the standard has_many class method. I will likely be waiting for Rails 3 to be released (and thus the new base ORM implementation) before attempting the association proxy route.
|
61
|
+
|
62
|
+
=== Thanks
|
63
|
+
|
64
|
+
Thanks to {James Reynolds}[http://drtoast.com/] for the great name and thanks to {Tanner Donovan}[http://github.com/ttdonovan] for patches and being the first production customer.
|
data/Rakefile
CHANGED
@@ -10,8 +10,7 @@ begin
|
|
10
10
|
gem.email = "brian@emphaticsolutions.com"
|
11
11
|
gem.homepage = "http://github.com/briandoll/st-elsewhere"
|
12
12
|
gem.authors = ["Brian Doll"]
|
13
|
-
|
14
|
-
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
13
|
+
gem.add_development_dependency "rr", ">= 0"
|
15
14
|
end
|
16
15
|
Jeweler::GemcutterTasks.new
|
17
16
|
rescue LoadError
|
@@ -21,7 +20,7 @@ end
|
|
21
20
|
require 'rake/testtask'
|
22
21
|
Rake::TestTask.new(:test) do |test|
|
23
22
|
test.libs << 'lib' << 'test'
|
24
|
-
test.pattern = 'test
|
23
|
+
test.pattern = 'test/*test.rb'
|
25
24
|
test.verbose = true
|
26
25
|
end
|
27
26
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.5
|
data/changelog.rdoc
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
0.1.5 "Ed Flanders"
|
2
|
+
- This is the first acceptable production release of st-elsewhere.
|
3
|
+
- Implements:
|
4
|
+
- has_many_elsewhere :association, :through => :through_association
|
5
|
+
- Provides:
|
6
|
+
- ARKlass#associations
|
7
|
+
- ARKlass#association_ids
|
8
|
+
- ARKlass#associations=
|
9
|
+
- ARKlass#association_ids=
|
data/lib/st-elsewhere.rb
CHANGED
@@ -5,8 +5,6 @@ module StElsewhere
|
|
5
5
|
#
|
6
6
|
# The following methods for retrieval and query of collections of associated objects will be added:
|
7
7
|
#
|
8
|
-
# [collection<<(object, ...)]
|
9
|
-
# TODO: Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
|
10
8
|
# [collection=objects]
|
11
9
|
# Replaces the collections content by deleting and adding objects as appropriate.
|
12
10
|
# [collection_singular_ids]
|
@@ -113,9 +111,9 @@ module StElsewhere
|
|
113
111
|
association_class = associations.first.class.to_s
|
114
112
|
ids = case association_class
|
115
113
|
when "String"
|
116
|
-
associations
|
117
|
-
when "Fixnum"
|
118
114
|
associations.map{|a| a.to_i }
|
115
|
+
when "Fixnum"
|
116
|
+
associations
|
119
117
|
else
|
120
118
|
associations.map{|a| a.id}
|
121
119
|
end
|
data/st-elsewhere.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{st-elsewhere}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brian Doll"]
|
12
|
-
s.date = %q{2009-11-
|
12
|
+
s.date = %q{2009-11-21}
|
13
13
|
s.description = %q{This gem provides has_many_elsewhere, an ActiveRecord class method to support many to many relationships in Rails applications, across multiple database connections.}
|
14
14
|
s.email = %q{brian@emphaticsolutions.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
"README.rdoc",
|
21
21
|
"Rakefile",
|
22
22
|
"VERSION",
|
23
|
+
"changelog.rdoc",
|
23
24
|
"lib/st-elsewhere.rb",
|
24
25
|
"st-elsewhere.gemspec",
|
25
26
|
"tasks/st-elsewhere_tasks.rake",
|
@@ -41,9 +42,12 @@ Gem::Specification.new do |s|
|
|
41
42
|
s.specification_version = 3
|
42
43
|
|
43
44
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
45
|
+
s.add_development_dependency(%q<rr>, [">= 0"])
|
44
46
|
else
|
47
|
+
s.add_dependency(%q<rr>, [">= 0"])
|
45
48
|
end
|
46
49
|
else
|
50
|
+
s.add_dependency(%q<rr>, [">= 0"])
|
47
51
|
end
|
48
52
|
end
|
49
53
|
|
data/test/st-elsewhere_test.rb
CHANGED
@@ -1,8 +1,65 @@
|
|
1
|
+
# These tests are insanely incomplete. Testing a module like this without
|
2
|
+
# depending on an encompasing Rails application is quite difficult. These
|
3
|
+
# tests use mocks on the objects under test, which feels almost useless.
|
4
|
+
# I may consider publishing an accompanyhing Rails application with a test
|
5
|
+
# suite that tests this module in a usable state.
|
6
|
+
|
1
7
|
require 'test_helper'
|
8
|
+
require 'st-elsewhere'
|
2
9
|
|
3
|
-
class
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
10
|
+
class Doctor < Struct.new :id, :name
|
11
|
+
end
|
12
|
+
|
13
|
+
class HospitalDoctor < Struct.new :id, :doctor_id, :hospital_id
|
14
|
+
attr_accessor :doctor, :hospital
|
8
15
|
end
|
16
|
+
|
17
|
+
class Hospital < Struct.new :id, :name
|
18
|
+
extend StElsewhere
|
19
|
+
has_many_elsewhere :doctors, :through => :hospital_doctors
|
20
|
+
end
|
21
|
+
|
22
|
+
class StElsewhereTest < Test::Unit::TestCase
|
23
|
+
|
24
|
+
def setup
|
25
|
+
@hospital = Hospital.new
|
26
|
+
@hospital.id = 1
|
27
|
+
@hospital.name = "St. Elsewhere"
|
28
|
+
|
29
|
+
@doctor = Doctor.new
|
30
|
+
@doctor.id = 1
|
31
|
+
@doctor.name = "Dr. Foo"
|
32
|
+
|
33
|
+
@doctor2 = Doctor.new
|
34
|
+
@doctor2.id = 2
|
35
|
+
@doctor2.name = "Dr. Bar"
|
36
|
+
|
37
|
+
@hospital_doctor = HospitalDoctor.new
|
38
|
+
@hospital_doctor.id = 1
|
39
|
+
@hospital_doctor.doctor_id = @doctor.id
|
40
|
+
@hospital_doctor.hospital_id = @hospital.id
|
41
|
+
|
42
|
+
@hospital_doctor2 = HospitalDoctor.new
|
43
|
+
@hospital_doctor2.id = 2
|
44
|
+
@hospital_doctor2.doctor_id = @doctor2.id
|
45
|
+
@hospital_doctor2.hospital_id = @hospital.id
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_basic_obj_setup
|
49
|
+
assert "St. Elsewhere".eql?(@hospital.name)
|
50
|
+
assert @hospital.respond_to? :doctors
|
51
|
+
assert @hospital.respond_to? :doctors=
|
52
|
+
assert @hospital.respond_to? :doctor_ids
|
53
|
+
assert @hospital.respond_to? :doctor_ids=
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_basic_functionality
|
57
|
+
mock(@hospital_doctor).doctor {@doctor}
|
58
|
+
mock(@hospital_doctor2).doctor {@doctor2}
|
59
|
+
mock(HospitalDoctor).find([1,2]) {[@hospital_doctor, @hospital_doctor2]}
|
60
|
+
mock(@hospital).hospital_doctor_ids {[@hospital_doctor.id, @hospital_doctor2.id]}
|
61
|
+
|
62
|
+
assert @hospital.doctors.eql?([@doctor, @doctor2])
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: st-elsewhere
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Doll
|
@@ -9,10 +9,19 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-21 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rr
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
16
25
|
description: This gem provides has_many_elsewhere, an ActiveRecord class method to support many to many relationships in Rails applications, across multiple database connections.
|
17
26
|
email: brian@emphaticsolutions.com
|
18
27
|
executables: []
|
@@ -26,6 +35,7 @@ files:
|
|
26
35
|
- README.rdoc
|
27
36
|
- Rakefile
|
28
37
|
- VERSION
|
38
|
+
- changelog.rdoc
|
29
39
|
- lib/st-elsewhere.rb
|
30
40
|
- st-elsewhere.gemspec
|
31
41
|
- tasks/st-elsewhere_tasks.rake
|