sundbp-dm-polymorphic 0.10.2

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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Daniel Neighman
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 ADDED
@@ -0,0 +1,51 @@
1
+ Please see wiki for discussion.
2
+
3
+ The DM polymorphic gem mimics AR style polymorphism. It has been decided that DM will not follow this path, since it
4
+ really isn't very nice on the DB and there are other ways, that do not require DBA to cry to achieve the same result.
5
+
6
+ That being said this is still useful for those ppl wishing to convert rails apps over.
7
+
8
+ One Massive Caveat is that using this you will get n+1 calls to the db atm if you do Comments#commentable for example. It needs a proxy object if anyone cares to write one.
9
+
10
+ This is highly experimental software, use it at your own risk.
11
+
12
+ ==== Example Usage.
13
+
14
+ class Comment
15
+ include DataMapper::Resource
16
+
17
+ is :polymorphic, :commentable
18
+
19
+ property :id, Integer, :serial => true
20
+ property :text, String
21
+ end
22
+
23
+ class Post
24
+ include DataMapper::Resource
25
+
26
+ property :id, Integer, :serial => true
27
+ property :name, String
28
+
29
+ has n, :comments, :polymorphically => :commentable
30
+ end
31
+
32
+ class Article
33
+ include DataMapper::Resource
34
+
35
+ property :id, Integer, :serial => true
36
+ property :name, String
37
+
38
+ has n, :comments, :polymorphically => :commentable
39
+ end
40
+
41
+ This will then provide the following methods
42
+
43
+ Comment#commentable
44
+ Comment#post
45
+ Comment#article
46
+ Post#comments
47
+ Article#comments
48
+
49
+ What is needed is a
50
+ Comment.commentables or something method so there is a nice proxy to avoid having all the loading issues.
51
+
data/Rakefile ADDED
@@ -0,0 +1,60 @@
1
+ require "rubygems"
2
+ require "spec"
3
+ require "rake/clean"
4
+ require "rake/gempackagetask"
5
+ require "spec/rake/spectask"
6
+ require "pathname"
7
+
8
+ CLEAN.include "{log,pkg}/"
9
+
10
+ spec = Gem::Specification.new do |s|
11
+ s.name = "sundbp-dm-polymorphic"
12
+ s.version = "0.10.2"
13
+ s.platform = Gem::Platform::RUBY
14
+ s.has_rdoc = true
15
+ s.extra_rdoc_files = %w[ README LICENSE TODO ]
16
+ s.summary = "DataMapper plugin enabling simple ActiveRecord style polymorphism"
17
+ s.description = s.summary
18
+ s.author = "Daniel Neighman, Wayne E. Seguin, Ripta Pasay"
19
+ s.email = "has.sox@gmail.com, wayneeseguin@gmail.com, github@r8y.org"
20
+ s.homepage = "http://github.com/hassox/dm-polymorphic"
21
+ s.require_path = "lib"
22
+ s.files = FileList[ "{lib,spec}/**/*.rb", "spec/spec.opts", "Rakefile", *s.extra_rdoc_files ]
23
+ s.add_dependency("dm-core", ">=#{s.version}")
24
+ end
25
+
26
+ task :default => [ :spec ]
27
+
28
+ WIN32 = (RUBY_PLATFORM =~ /win32|mingw|cygwin/) rescue nil
29
+ SUDO = WIN32 ? "" : ("sudo" unless ENV["SUDOLESS"])
30
+
31
+ Rake::GemPackageTask.new(spec) do |pkg|
32
+ pkg.gem_spec = spec
33
+ end
34
+
35
+ desc "Install #{spec.name} #{spec.version} (default ruby)"
36
+ task :install => [ :package ] do
37
+ sh "#{SUDO} gem install pkg/#{spec.name}-#{spec.version} --no-update-sources", :verbose => false
38
+ end
39
+
40
+ namespace :jruby do
41
+ desc "Install #{spec.name} #{spec.version} with JRuby"
42
+ task :install => [ :package ] do
43
+ sh %{#{SUDO} jruby -S gem install --local pkg/#{spec.name}-#{spec.version} --no-update-sources}, :verbose => false
44
+ end
45
+ end
46
+
47
+ desc "Run specifications"
48
+ Spec::Rake::SpecTask.new(:spec) do |t|
49
+ t.spec_opts << "--options" << "spec/spec.opts" if File.exists?("spec/spec.opts")
50
+ t.spec_files = Pathname.glob(Pathname.new(__FILE__).dirname + "spec/**/*_spec.rb")
51
+
52
+ begin
53
+ t.rcov = ENV.has_key?("NO_RCOV") ? ENV["NO_RCOV"] != "true" : true
54
+ t.rcov_opts << "--exclude" << "spec"
55
+ t.rcov_opts << "--text-summary"
56
+ t.rcov_opts << "--sort" << "coverage" << "--sort-reverse"
57
+ rescue Exception
58
+ # rcov not installed
59
+ end
60
+ end
data/TODO ADDED
File without changes
@@ -0,0 +1,25 @@
1
+ module DataMapper
2
+ module Model
3
+ module Relationship
4
+
5
+ alias_method :has_without_polymorphism, :has
6
+
7
+ def has(cardinality, name, *args)
8
+ opts = args.extract_options!
9
+ if interface = opts.delete(:polymorphically)
10
+ # get the child model
11
+ child_model_name = opts.fetch(:class_name, Extlib::Inflection.classify(name))
12
+ child_klass = Extlib::Inflection.constantize(child_model_name)
13
+ belongs_to_name = Extlib::Inflection.underscore(Extlib::Inflection.demodulize(self.name))
14
+
15
+ # Setup the has with the right stuff
16
+ has_without_polymorphism cardinality, name, :child_key => [:"#{interface}_id"], :"#{interface}_class" => self
17
+ child_klass.belongs_to :"#{belongs_to_name}", :child_key => [:"#{interface}_id"], :"#{interface}_class" => self
18
+ else
19
+ has_without_polymorphism(cardinality, name, *(args + [opts]))
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,46 @@
1
+ require "rubygems"
2
+ require "pathname"
3
+
4
+ gem "dm-core", ">=0.10.0"
5
+ require "dm-core"
6
+
7
+
8
+ module DataMapper
9
+ module Is
10
+ module Polymorphic
11
+
12
+ def is_polymorphic(name, id_type = Serial)
13
+ self.class_eval <<-EOS, __FILE__, __LINE__
14
+ property :"#{name}_class", Klass
15
+ property :"#{name}_id", #{id_type}
16
+
17
+ def #{name}
18
+ return nil if self.#{name}_class.nil? || self.#{name}_class == NilClass
19
+ return nil if self.#{name}_id.nil?
20
+ if (self.#{name}_class.class == Class)
21
+ self.#{name}_class.get(self.#{name}_id)
22
+ else
23
+ klass = Kernel.const_get(self.#{name}_class.to_s)
24
+ if klass.ancestors.include? DataMapper::Resource
25
+ klass.get(self.#{name}_id)
26
+ else
27
+ nil
28
+ end
29
+ end
30
+ end
31
+
32
+ def #{name}=(entity)
33
+ self.#{name}_class = entity.class
34
+ self.#{name}_id = entity.id
35
+ end
36
+ EOS
37
+ end
38
+
39
+ end # Polymophic
40
+ end # Is
41
+ end
42
+
43
+ DataMapper::Model.append_extensions DataMapper::Is::Polymorphic
44
+
45
+ require Pathname(__FILE__).dirname.expand_path / "associations.rb"
46
+ require Pathname(__FILE__).dirname.expand_path / "types.rb"
data/lib/tester.rb ADDED
@@ -0,0 +1,50 @@
1
+ require File.join(File.dirname(__FILE__), "dm-polymorphic")
2
+
3
+ DataMapper::Logger.new(STDOUT, :debug)
4
+ DataMapper.setup(:default, 'sqlite3::memory:')
5
+
6
+ class Comment
7
+ include DataMapper::Resource
8
+
9
+ is :polymorphic, :commentable
10
+
11
+ property :id, Integer, :serial => true
12
+ property :text, String
13
+ end
14
+
15
+ class Post
16
+ include DataMapper::Resource
17
+
18
+ property :id, Integer, :serial => true
19
+ property :name, String
20
+
21
+ has n, :comments, :polymorphically => :commentable
22
+ end
23
+
24
+ class Article
25
+ include DataMapper::Resource
26
+
27
+ property :id, Integer, :serial => true
28
+ property :name, String
29
+
30
+ has n, :comments, :polymorphically => :commentable
31
+ end
32
+
33
+ Comment.auto_migrate!
34
+ Post.auto_migrate!
35
+ Article.auto_migrate!
36
+
37
+ post1 = Post.create(:name => "post1")
38
+ article1 = Article.create(:name => "article1")
39
+ post2 = Post.create(:name => "post2")
40
+ article2 = Article.create(:name => "article2")
41
+
42
+ %w(one two three four five six seven eight nine ten).each_with_index do |text, index|
43
+ [post1, post2, article1, article2].each do |item|
44
+ item.comments << Comment.new(:text => text)
45
+ end
46
+ end
47
+
48
+ Comment.all.each do |c|
49
+ puts "COMMENT: #{c.text} - #{c.commentable}"
50
+ end
data/lib/types.rb ADDED
@@ -0,0 +1,7 @@
1
+ module DataMapper
2
+ module Types
3
+ class Klass < DataMapper::Type
4
+ primitive Class
5
+ end # class Klass
6
+ end # module Types
7
+ end # module DataMapper
@@ -0,0 +1,121 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
2
+
3
+ DataMapper::Logger.new(STDOUT, :debug)
4
+
5
+ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
6
+ describe "DataMapper::Polymorphic" do
7
+
8
+ class Comment
9
+ include DataMapper::Resource
10
+
11
+ is :polymorphic, :commentable
12
+
13
+ property :id, Serial
14
+ property :text, String
15
+ end
16
+
17
+ class Post
18
+ include DataMapper::Resource
19
+
20
+ property :id, Serial
21
+ property :name, String
22
+
23
+ has n, :comments, :polymorphically => :commentable
24
+ end
25
+
26
+ class Article
27
+ include DataMapper::Resource
28
+
29
+ property :id, Serial
30
+ property :name, String
31
+
32
+ has n, :comments, :polymorphically => :commentable
33
+ end
34
+
35
+ before :each do
36
+ Comment.auto_migrate!
37
+ Post.auto_migrate!
38
+ Article.auto_migrate!
39
+ end
40
+
41
+ [Article, Post].each do |klass|
42
+ it "should create an associated object for #{klass}" do
43
+ item = klass.create(:name => "item1")
44
+ item.reload
45
+ item.comments.create(:text => "A Comment")
46
+ item.reload
47
+ item.comments(:text => "A Comment").should have(1).item
48
+ end
49
+
50
+ it "should add the comment with the << syntax for #{klass}" do
51
+ item = klass.create(:name => "item2")
52
+ c = Comment.new(:text => "comment2")
53
+ item.comments << c
54
+ c.save
55
+ item.reload
56
+ item.comments(:text => "comment2").should have(1).item
57
+ end
58
+
59
+ it "should not add the comment with the << syntax for #{klass} if comment was not saved" do
60
+ item = klass.create(:name => "item2a")
61
+ c = Comment.new(:text => "comment2a")
62
+ item.comments << c
63
+ item.reload
64
+ item.comments(:text => "comment2a").should have(0).item
65
+ end
66
+
67
+ it "should access all the comments from the post for #{klass}" do
68
+ item = klass.create(:name => "item3")
69
+ c1 = Comment.new(:text => "comment3")
70
+ c2 = Comment.new(:text => "comment4")
71
+ [c1,c2].each{|c| item.comments << c}
72
+ item.comments.save
73
+ item.reload
74
+ item.comments.should have(2).items
75
+ end
76
+
77
+ it "should access the post from the comment for #{klass}" do
78
+ item = klass.create(:name => "item4")
79
+ c = Comment.new(:text => "comment5")
80
+ item.comments << c
81
+ item.save
82
+ c.send(Extlib::Inflection.underscore(klass.name).to_sym).should == item
83
+ end
84
+
85
+ it "should access the commentable from the comment for #{klass}" do
86
+ item = klass.create(:name => "item5")
87
+ c = Comment.new(:text => "comment6")
88
+ item.comments << c
89
+ c.save
90
+ item.reload; c.reload
91
+ c.commentable.should == item
92
+ end
93
+ end
94
+
95
+ # it "should only make one query to each Model" do
96
+ # post1 = Post.create(:name => "post1")
97
+ # article1 = Article.create(:name => "article1")
98
+ # post2 = Post.create(:name => "post2")
99
+ # article2 = Article.create(:name => "article2")
100
+ #
101
+ # %w(one two three four five six seven eight nine ten).each_with_index do |text, index|
102
+ # [post1, post2, article1, article2].each do |item|
103
+ # item.comments.create(:text => text)
104
+ # end
105
+ # end
106
+ #
107
+ # Post.all.each do |c|
108
+ # puts "COMMENT: #{c.text} - #{c.commentable_class}"
109
+ # end
110
+ #
111
+ # Post.should_receive(:all).once
112
+ # Article.should_receive(:all).once.and_return(Article.comments)
113
+ #
114
+ # Comment.all.each do |comment|
115
+ # [Post, Article].should include(comment.commentable.class)
116
+ # end
117
+ # end
118
+
119
+ end
120
+ end
121
+
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --format specdoc
2
+ --colour
@@ -0,0 +1,31 @@
1
+ require "rubygems"
2
+ require "pathname"
3
+
4
+ gem "dm-core", ">=0.10.0"
5
+ require "dm-core"
6
+
7
+ spec_dir_path = Pathname(__FILE__).dirname.expand_path
8
+ require spec_dir_path.parent + "lib/dm-polymorphic"
9
+
10
+ def load_driver(name, default_uri)
11
+ return false if ENV["ADAPTER"] != name.to_s
12
+
13
+ lib = "do_#{name}"
14
+
15
+ begin
16
+ gem lib, ">=0.10.0"
17
+ require lib
18
+ DataMapper.setup(name, ENV["#{name.to_s.upcase}_SPEC_URI"] || default_uri)
19
+ DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[name]
20
+ true
21
+ rescue Gem::LoadError => e
22
+ warn "Could not load #{lib}: #{e}"
23
+ false
24
+ end
25
+ end
26
+
27
+ ENV["ADAPTER"] ||= "sqlite3"
28
+
29
+ HAS_SQLITE3 = load_driver(:sqlite3, "sqlite3::memory:")
30
+ HAS_MYSQL = load_driver(:mysql, "mysql://localhost/dm_core_test")
31
+ HAS_POSTGRES = load_driver(:postgres, "postgres://postgres@localhost/dm_core_test")
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sundbp-dm-polymorphic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.10.2
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Neighman, Wayne E. Seguin, Ripta Pasay
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-12 00:00:00 +00:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: dm-core
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.10.2
24
+ version:
25
+ description: DataMapper plugin enabling simple ActiveRecord style polymorphism
26
+ email: has.sox@gmail.com, wayneeseguin@gmail.com, github@r8y.org
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README
33
+ - LICENSE
34
+ - TODO
35
+ files:
36
+ - lib/associations.rb
37
+ - lib/dm-polymorphic.rb
38
+ - lib/tester.rb
39
+ - lib/types.rb
40
+ - spec/dm-polymorphic_spec.rb
41
+ - spec/spec_helper.rb
42
+ - spec/spec.opts
43
+ - Rakefile
44
+ - README
45
+ - LICENSE
46
+ - TODO
47
+ has_rdoc: true
48
+ homepage: http://github.com/hassox/dm-polymorphic
49
+ licenses: []
50
+
51
+ post_install_message:
52
+ rdoc_options: []
53
+
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ requirements: []
69
+
70
+ rubyforge_project:
71
+ rubygems_version: 1.3.5
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: DataMapper plugin enabling simple ActiveRecord style polymorphism
75
+ test_files: []
76
+