sequel_polymorphic 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0ba44333d65bad98de9c9645057d24ddc8513242
4
+ data.tar.gz: d44a526e09d8cca923ff8a3e61fe8bd6f9baca1d
5
+ SHA512:
6
+ metadata.gz: ccda128f94078c89326d8f98af390f7382d0f79a4927d6836dbca2e35111e77b056c9ebfafeb2e11027488824728f4f9c8e9904c6591ea3832d553eb2f951c08
7
+ data.tar.gz: 62157d1f0941c1762aa686ef784439b6f79be198f15839067a6e522e569fe15559bd605efed8f1a736a29c22d16b6a298ca8711efbb67a018396a5fd4f5dc757
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Jack Dempsey
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.
@@ -0,0 +1,122 @@
1
+ #Sequel Polymorphic
2
+
3
+ A simple plugin for Sequel::Model's that lets you easily create polymorphic associations.
4
+
5
+ ##ActiveRecord Style
6
+
7
+ ```ruby
8
+ class Asset < ActiveRecord::Base
9
+ belongs_to :attachable, :polymorphic => true
10
+ end
11
+
12
+ class Post < ActiveRecord::Base
13
+ has_many :assets, :as => :attachable
14
+ end
15
+
16
+ class Note < ActiveRecord::Base
17
+ has_many :assets, :as => :attachable
18
+ end
19
+
20
+ @asset.attachable = @post
21
+ @asset.attachable = @note
22
+ ```
23
+
24
+ ## Sequel (without plugin)
25
+
26
+ In Sequel you would do the following:
27
+
28
+ ```ruby
29
+ class Asset < Sequel::Model
30
+ many_to_one :attachable, :reciprocal=>:assets, \
31
+ :dataset=>(proc do
32
+ klass = attachable_type.constantize
33
+ klass.filter(klass.primary_key=>attachable_id)
34
+ end), \
35
+ :eager_loader=>(proc do |key_hash, assets, associations|
36
+ id_map = {}
37
+ assets.each do |asset|
38
+ asset.associations[:attachable] = nil
39
+ ((id_map[asset.attachable_type] ||= {})[asset.attachable_id] ||= []) << asset
40
+ end
41
+ id_map.each do |klass_name, id_map|
42
+ klass = klass_name.constantize
43
+ klass.filter(klass.primary_key=>id_map.keys).all do |attach|
44
+ id_map[attach.pk].each do |asset|
45
+ asset.associations[:attachable] = attach
46
+ end
47
+ end
48
+ end
49
+ end)
50
+
51
+ private
52
+
53
+ def _attachable=(attachable)
54
+ self[:attachable_id] = (attachable.pk if attachable)
55
+ self[:attachable_type] = (attachable.class.name if attachable)
56
+ end
57
+ end
58
+
59
+ class Post < Sequel::Model
60
+ one_to_many :assets, :key=>:attachable_id do |ds|
61
+ ds.filter(:attachable_type=>'Post')
62
+ end
63
+
64
+ private
65
+
66
+ def _add_asset(asset)
67
+ asset.attachable_id = pk
68
+ asset.attachable_type = 'Post'
69
+ asset.save
70
+ end
71
+ def _remove_asset(asset)
72
+ asset.attachable_id = nil
73
+ asset.attachable_type = nil
74
+ asset.save
75
+ end
76
+ def _remove_all_assets
77
+ Asset.filter(:attachable_id=>pk, :attachable_type=>'Post')\
78
+ .update(:attachable_id=>nil, :attachable_type=>nil)
79
+ end
80
+ end
81
+
82
+ class Note < Sequel::Model
83
+ one_to_many :assets, :key=>:attachable_id do |ds|
84
+ ds.filter(:attachable_type=>'Note')
85
+ end
86
+
87
+ private
88
+
89
+ def _add_asset(asset)
90
+ asset.attachable_id = pk
91
+ asset.attachable_type = 'Note'
92
+ asset.save
93
+ end
94
+ def _remove_asset(asset)
95
+ asset.attachable_id = nil
96
+ asset.attachable_type = nil
97
+ asset.save
98
+ end
99
+ def _remove_all_assets
100
+ Asset.filter(:attachable_id=>pk, :attachable_type=>'Note')\
101
+ .update(:attachable_id=>nil, :attachable_type=>nil)
102
+ end
103
+ end
104
+
105
+ @asset.attachable = @post
106
+ @asset.attachable = @note
107
+ ```
108
+
109
+ Thats quite a bit of code. With sequel_polymorphic you can now do:
110
+
111
+ ## Polymorphic
112
+
113
+ ```ruby
114
+ class Note < Sequel::Model
115
+ one_to_many :assets, :as => :attachable
116
+ end
117
+
118
+ class Asset < Sequel::Model
119
+ many_to_one :attachable, :polymorphic => true
120
+ end
121
+
122
+ ```
data/TODO ADDED
File without changes
@@ -0,0 +1,4 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'sequel_polymorphic/sequel_polymorphic'
@@ -0,0 +1,117 @@
1
+ module Sequel
2
+ module Plugins
3
+ module Polymorphic
4
+ # Apply the plugin to the model.
5
+ def self.apply(model, options = {})
6
+ end
7
+
8
+ module InstanceMethods
9
+
10
+ end
11
+
12
+ module ClassMethods
13
+
14
+ # Example: Comment.many_to_one :commentable, polymorphic: true
15
+ def many_to_one(*args, &block)
16
+ able, options = *args
17
+ options ||= {}
18
+
19
+ if options[:polymorphic]
20
+ model = self.to_s.downcase # comment
21
+ plural_model = pluralize(model) # comments
22
+
23
+ associate(:many_to_one, able,
24
+ :reciprocal => plural_model.to_sym,
25
+ :setter => (proc do |able_instance|
26
+ self[:"#{able}_id"] = (able_instance.pk if able_instance)
27
+ self[:"#{able}_type"] = (able_instance.class.name if able_instance)
28
+ end),
29
+ :dataset => (proc do
30
+ klass = constantize(send(:"#{able}_type"))
31
+ klass.where(klass.primary_key => send(:"#{able}_id"))
32
+ end),
33
+ :eager_loader => (proc do |eo|
34
+ id_map = {}
35
+ eo[:rows].each do |model|
36
+ model.associations[able] = nil
37
+ ((id_map[model.send(:"#{able}_type")] ||= {})[model.send(:"#{able}_id")] ||= []) << model
38
+ end
39
+ id_map.each do |klass_name, id_map|
40
+ klass = constantize(klass_name)
41
+ klass.where(klass.primary_key=>id_map.keys).all do |related_obj|
42
+ id_map[related_obj.pk].each do |model|
43
+ model.associations[able] = related_obj
44
+ end
45
+ end
46
+ end
47
+ end)
48
+ )
49
+
50
+ else
51
+ associate(:many_to_one, *args, &block)
52
+ end
53
+ end
54
+
55
+ alias :belongs_to :many_to_one
56
+
57
+
58
+ # Creates a one-to-many relationship. NB: Removing/clearing nullifies the *able fields in the related objects
59
+ # Example: Post.one_to_many :comments, as: :commentable
60
+ def one_to_many(*args, &block)
61
+ collection_name, options = *args
62
+ options ||= {}
63
+
64
+ if able = options[:as]
65
+ able_id = :"#{able}_id"
66
+ able_type = :"#{able}_type"
67
+ many_dataset_name = :"#{collection_name}_dataset"
68
+
69
+ associate(:one_to_many, collection_name,
70
+ :key => able_id,
71
+ :reciprocal => able,
72
+ :conditions => {able_type => self.to_s},
73
+ :adder => proc { |many_of_instance| many_of_instance.update(able_id => pk, able_type => self.class.to_s) },
74
+ :remover => proc { |many_of_instance| many_of_instance.update(able_id => nil, able_type => nil) },
75
+ :clearer => proc { send(many_dataset_name).update(able_id => nil, able_type => nil) }
76
+ )
77
+
78
+ else
79
+ associate(:one_to_many, *args, &block)
80
+ end
81
+ end
82
+
83
+ alias :has_many :one_to_many
84
+
85
+
86
+ # Creates a many-to-many relationship. NB: Removing/clearing the collection deletes the instances in the through relationship (as opposed to nullifying the *able fields as in the one-to-many)
87
+ # Example: Post.many_to_many :tags, :through => :taggings, :as => :taggable
88
+ def many_to_many(*args, &block)
89
+ collection_name, options = *args
90
+ options ||= {}
91
+
92
+ if through = (options[:through] || options[:join_table]) and able = options[:as]
93
+ able_id = :"#{able}_id"
94
+ able_type = :"#{able}_type"
95
+ collection_singular = singularize(collection_name.to_s).to_sym # => tag
96
+ collection_singular_id = :"#{collection_singular}_id"
97
+ through_klass = constantize(singularize(through.to_s).capitalize) # => Tagging
98
+
99
+ associate(:many_to_many, collection_name,
100
+ :left_key => able_id,
101
+ :join_table => through,
102
+ :conditions => {able_type => self.to_s},
103
+ :adder => proc { |many_of_instance| through_klass.create(collection_singular_id => many_of_instance.pk, able_id => pk, able_type => self.class.to_s) },
104
+ :remover => proc { |many_of_instance| through_klass.where(collection_singular_id => many_of_instance.pk, able_id => pk, able_type => self.class.to_s).delete },
105
+ :clearer => proc { through_klass.where(able_id => pk, able_type => self.class.to_s).delete }
106
+ )
107
+
108
+ else
109
+ associate(:many_to_many, *args, &block)
110
+ end
111
+ end
112
+ end # ClassMethods
113
+ end # Polymorphic
114
+ end # Plugins
115
+ end # Sequel
116
+
117
+
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sequel_polymorphic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jack Dempsey
8
+ - Dave Myron
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-09-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sequel
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '4.0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '4.0'
28
+ description: A gem that provides Sequel::Models with polymorphic association capabilities
29
+ email: therealdave.myron@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files:
33
+ - README.md
34
+ - LICENSE
35
+ - TODO
36
+ files:
37
+ - LICENSE
38
+ - README.md
39
+ - TODO
40
+ - lib/sequel_polymorphic.rb
41
+ - lib/sequel_polymorphic/sequel_polymorphic.rb
42
+ homepage: https://github.com/jackdempsey/sequel_polymorphic
43
+ licenses:
44
+ - MIT
45
+ metadata: {}
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 2.4.1
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: A gem that provides Sequel::Models with polymorphic association capabilities
66
+ test_files: []