Updated to work with sequel 3.x #2

Closed
wants to merge 20 commits into
from
+106 −151
Split
View
3 .gitignore
@@ -0,0 +1,3 @@
+.rvmrc
+.bundle
+Gemfile.lock
View
8 Gemfile
@@ -0,0 +1,8 @@
+#:set filetype=ruby
+# load everything else from the standard gem server
+source :rubygems
+
+gem "rake"
+gem "sqlite3-ruby", "~> 1.3.2"
+gem "sequel", "~> 3.16.0"
+gem "rspec", "~> 1.3.1"
View
118 README
@@ -1,118 +0,0 @@
-Sequel Polymorphic
-==================
-
-A simple plugin for Sequel::Model's that lets you easily create polymorphic associations.
-
-ActiveRecord Style
-------------------
-
-class Asset < ActiveRecord::Base
- belongs_to :attachable, :polymorphic => true
-end
-
-class Post < ActiveRecord::Base
- has_many :assets, :as => :attachable
-end
-
-class Note < ActiveRecord::Base
- has_many :assets, :as => :attachable
-end
-
-@asset.attachable = @post
-@asset.attachable = @note
-
-In Sequel you would do the following:
-
-class Asset < Sequel::Model
- many_to_one :attachable, :reciprocal=>:assets, \
- :dataset=>(proc do
- klass = attachable_type.constantize
- klass.filter(klass.primary_key=>attachable_id)
- end), \
- :eager_loader=>(proc do |key_hash, assets, associations|
- id_map = {}
- assets.each do |asset|
- asset.associations[:attachable] = nil
- ((id_map[asset.attachable_type] ||= {})[asset.attachable_id] ||= []) << asset
- end
- id_map.each do |klass_name, id_map|
- klass = klass_name.constantize
- klass.filter(klass.primary_key=>id_map.keys).all do |attach|
- id_map[attach.pk].each do |asset|
- asset.associations[:attachable] = attach
- end
- end
- end
- end)
-
- private
-
- def _attachable=(attachable)
- self[:attachable_id] = (attachable.pk if attachable)
- self[:attachable_type] = (attachable.class.name if attachable)
- end
-end
-
-class Post < Sequel::Model
- one_to_many :assets, :key=>:attachable_id do |ds|
- ds.filter(:attachable_type=>'Post')
- end
-
- private
-
- def _add_asset(asset)
- asset.attachable_id = pk
- asset.attachable_type = 'Post'
- asset.save
- end
- def _remove_asset(asset)
- asset.attachable_id = nil
- asset.attachable_type = nil
- asset.save
- end
- def _remove_all_assets
- Asset.filter(:attachable_id=>pk, :attachable_type=>'Post')\
- .update(:attachable_id=>nil, :attachable_type=>nil)
- end
-end
-
-class Note < Sequel::Model
- one_to_many :assets, :key=>:attachable_id do |ds|
- ds.filter(:attachable_type=>'Note')
- end
-
- private
-
- def _add_asset(asset)
- asset.attachable_id = pk
- asset.attachable_type = 'Note'
- asset.save
- end
- def _remove_asset(asset)
- asset.attachable_id = nil
- asset.attachable_type = nil
- asset.save
- end
- def _remove_all_assets
- Asset.filter(:attachable_id=>pk, :attachable_type=>'Note')\
- .update(:attachable_id=>nil, :attachable_type=>nil)
- end
-end
-
-@asset.attachable = @post
-@asset.attachable = @note
-
-
-Thats quite a bit of code. With sequel_polymorphic you can now do:
-
-class Note < Sequel::Model
- is :polymorphic
- one_to_many :assets, :as => :attachable
-end
-
-class Asset < Sequel::Model
- is :polymorphic
- many_to_one :attachable, :polymorphic => true
-end
-
-voila!
View
60 README.md
@@ -0,0 +1,60 @@
+# Sequel Polymorphic
+
+A simple plugin for Sequel::Model's that lets you easily create polymorphic associations.
+
+## Usage
+
+### Models
+
+```ruby
+Sequel::Model.plugin(:polymorphic)
+
+class Asset < Sequel::Model
+ belongs_to :attachable, :polymorphic => true
+end
+
+class Note < Sequel::Model
+ has_many :assets, :as => :attachable
+end
+
+class Post < Sequel::Model
+ has_many :assets, :as => :attachable
+end
+```
+### Schema
+
+Include the polymorphic columns in your DB schema:
+
+```ruby
+Sequel.migration do
+ change do
+ create_table :assets do
+ # ...
+ Integer :attachable_id
+ String :attachable_type
+ # ...
+ index [:attachable_id, :attachable_type]
+ end
+ end
+end
+```
+
+## Similar to ActiveRecord Style
+
+```ruby
+class Asset < ActiveRecord::Base
+ belongs_to :attachable, :polymorphic => true
+end
+
+class Post < ActiveRecord::Base
+ has_many :assets, :as => :attachable
+end
+
+class Note < ActiveRecord::Base
+ has_many :assets, :as => :attachable
+end
+```
+
+## Sequel (without the polymorphic plugin)
+
+Check the [Advanced Associations](http://sequel.rubyforge.org/rdoc/files/doc/advanced_associations_rdoc.html) section of the [Sequel](http://sequel.rubyforge.org) docs (search "Polymorphic Associations")
View
10 Rakefile
@@ -5,9 +5,9 @@ require 'date'
require 'spec/rake/spectask'
GEM = "sequel_polymorphic"
-GEM_VERSION = "0.0.2"
-AUTHOR = "Jack Dempsey"
-EMAIL = "jack.dempsey@gmail.com"
+GEM_VERSION = "0.0.3"
+AUTHORS = "Jack Dempsey,Saimon Moore"
+EMAILS = "jack.dempsey@gmail.com,saimonmoore@gmail.com"
HOMEPAGE = "http://jackndempsey.blogspot.com"
SUMMARY = "A gem that provides Sequel::Models with polymorphic association capabilities"
@@ -19,8 +19,8 @@ spec = Gem::Specification.new do |s|
s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
s.summary = SUMMARY
s.description = s.summary
- s.author = AUTHOR
- s.email = EMAIL
+ s.authors = AUTHORS.split(',')
+ s.email = EMAILS.split(',')
s.homepage = HOMEPAGE
# Uncomment this to add a dependency
View
28 lib/sequel_polymorphic/sequel_polymorphic.rb → lib/sequel/plugins/polymorphic.rb
@@ -1,12 +1,15 @@
+require 'sequel/extensions/blank'
+require 'sequel/extensions/inflector'
+
module Sequel
module Plugins
module Polymorphic
+
# Apply the plugin to the model.
- def self.apply(model, options = {})
+ def self.apply(model_class, *arguments, &block)
end
- module InstanceMethods
-
+ def self.configure(model_class, *arguments, &block)
end
module ClassMethods
@@ -20,9 +23,9 @@ def many_to_one(*args, &block)
self.class_eval %{
associate(:many_to_one, :#{able}, :reciprocal=>:#{plural_model},
:dataset=>(proc { klass = #{able}_type.constantize; klass.filter(klass.primary_key=>#{able}_id) }),
- :eager_loader=>(proc do |key_hash, #{plural_model}, associations|
+ :eager_loader=>(proc do |eo|
id_map = {}
- #{plural_model}.each do |#{singular_model}|
+ eo[:rows].each do |#{singular_model}|
#{singular_model}.associations[:#{able}] = nil;
((id_map[#{singular_model}.#{able}_type] ||= {})[#{singular_model}.#{able}_id] ||= []) << #{singular_model}
end
@@ -34,9 +37,9 @@ def many_to_one(*args, &block)
end
end)
)
-
+
private
-
+
def _#{able}=(#{able})
self[:#{able}_id] = (#{able}.pk if #{able})
self[:#{able}_type] = (#{able}.class.name if #{able})
@@ -46,21 +49,21 @@ def _#{able}=(#{able})
associate(:many_to_one, *args, &block)
end
end
-
+
alias :belongs_to :many_to_one
def one_to_many(*args, &block)
many_of_class, options = *args
options ||= {}
many_class = many_of_class.to_s.singularize
if able = options[:as]
- associate(:one_to_many, many_of_class, :key=>"#{able}_id".to_sym) do |ds|
+ associate(:one_to_many, many_of_class, :key=>"#{able}_id".to_sym, :reciprocal => nil) do |ds|
ds.filter("#{able}_type".to_sym => self.class.to_s)
end
method_definitions = %{
private
-
+
def _add_#{many_class}(#{many_class})
#{many_class}.#{able}_id = pk
#{many_class}.#{able}_type = '#{self}'
@@ -80,9 +83,9 @@ def _remove_all_#{many_of_class}
associate(:one_to_many, *args, &block)
end
end
-
+
alias :has_many :one_to_many
-
+
#example: many_to_many :tags, :through => :taggings, :as => :taggable
def many_to_many(*args, &block)
many_to_class, options = *args # => :tags, :through => :taggings, :as => :taggable
@@ -120,4 +123,3 @@ def _remove_all_#{many_to_class}
end # Plugins
end # Sequel
-
View
2 lib/sequel_polymorphic.rb
@@ -1,4 +1,4 @@
$:.unshift(File.dirname(__FILE__)) unless
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
-require 'sequel_polymorphic/sequel_polymorphic'
+require 'sequel/plugins/polymorphic'
View
12 sequel_polymorphic.gemspec
@@ -2,16 +2,16 @@
Gem::Specification.new do |s|
s.name = %q{sequel_polymorphic}
- s.version = "0.0.1"
+ s.version = "0.0.3"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
- s.authors = ["Jack Dempsey"]
+ s.authors = ["Jack Dempsey", "Saimon Moore"]
s.autorequire = %q{sequel_polymorphic}
- s.date = %q{2009-01-20}
+ s.date = %q{2010-11-26}
s.description = %q{A gem that provides Sequel::Models with polymorphic association capabilities}
- s.email = %q{jack.dempsey@gmail.com}
- s.extra_rdoc_files = ["README", "LICENSE", "TODO"]
- s.files = ["LICENSE", "README", "TODO", "lib/sequel_polymorphic", "lib/sequel_polymorphic/sequel_polymorphic.rb", "lib/sequel_polymorphic.rb"]
+ s.email = %q{jack.dempsey@gmail.com saimonmoore@gmail.com}
+ s.extra_rdoc_files = ["README.md", "LICENSE", "TODO"]
+ s.files = ["LICENSE", "README.md", "TODO", "lib/sequel_polymorphic.rb", "lib/sequel/plugins/polymorphic.rb"]
s.homepage = %q{http://jackndempsey.blogspot.com}
s.require_paths = ["lib"]
s.rubygems_version = %q{1.3.1}
View
6 spec/sequel-setup.rb
@@ -1,3 +1,6 @@
+Sequel::Model.plugin(:polymorphic)
+Sequel::Model.plugin(:schema)
+
DB = Sequel.sqlite
class Asset < Sequel::Model
@@ -8,7 +11,6 @@ class Asset < Sequel::Model
varchar :attachable_type
end
- is :polymorphic
belongs_to :attachable, :polymorphic => true
end
@@ -19,7 +21,6 @@ class Post < Sequel::Model
varchar :name
end
- is :polymorphic
has_many :assets, :as => :attachable
end
@@ -30,7 +31,6 @@ class Note < Sequel::Model
varchar :name
end
- is :polymorphic
has_many :assets, :as => :attachable
end
View
8 spec/sequel_polymorphic/sequel_polymorphic_spec.rb
@@ -21,8 +21,8 @@
describe Sequel::Plugins::Polymorphic do
before do
- Post.delete_all
- Asset.delete_all
+ Post.dataset.truncate
+ Asset.dataset.truncate
end
it "should create an add_asset method which associates an Asset with a Post" do
@@ -52,8 +52,8 @@
describe "one_to_many with many associated objects" do
before do
- Post.delete_all
- Asset.delete_all
+ Post.dataset.truncate
+ Asset.dataset.truncate
@post = Post.create(:name => 'test post')
@asset1 = Asset.create(:name => "post's first asset")
@asset2 = Asset.create(:name => "post's second asset")
View
2 spec/spec_helper.rb
@@ -5,8 +5,8 @@
require 'spec'
require 'sequel'
-require File.dirname(__FILE__) + '/sequel-setup'
require File.dirname(__FILE__) + '/../lib/sequel_polymorphic'
+require File.dirname(__FILE__) + '/sequel-setup'