Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

first working version (i think)

  • Loading branch information...
commit 204cf8bb015dc1d13a4b7c5dd00e83fb6f6490df 1 parent f74949b
@jackdempsey authored
View
58 lib/sequel_polymorphic/sequel_polymorphic.rb
@@ -3,20 +3,53 @@ module Plugins
module Polymorphic
# Apply the plugin to the model.
def self.apply(model, options = {})
+ plural_model = model.to_s.downcase.pluralize
+ singular_model = model.to_s.downcase.singularize
if as_variable = (options[:belongs_to] or options[:many_to_one])
# defining the polymorphic model
- model.class_eval %{associate(:many_to_one, #{as_variable}, :reciprocal=>:assets,
- :dataset=>(proc { klass = attachable_type.constantize; klass.filter(klass.primary_key=>attachable_id) }),
- :eager_loader=>(proc do |key_hash, assets, associations|
+ model.class_eval %{associate(:many_to_one, :#{as_variable}, :reciprocal=>:#{plural_model},
+ :dataset=>(proc { klass = #{as_variable}_type.constantize; klass.filter(klass.primary_key=>#{as_variable}_id) }),
+ :eager_loader=>(proc do |key_hash, #{plural_model}, associations|
id_map = {}
- assets.each { |asset| asset.associations[:attachable] = nil; ((id_map[asset.attachable_type] ||= {})[asset.attachable_id] ||= []) << asset }
+ #{plural_model}.each { |#{singular_model}| #{singular_model}.associations[:#{as_variable}] = nil; ((id_map[#{singular_model}.#{as_variable}_type] ||= {})[#{singular_model}.#{as_variable}_id] ||= []) << #{singular_model} }
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 { |asset| asset.associations[:attachable] = attach }
+ klass.filter(klass.primary_key=>id_map.keys).all do |related_obj|
+ id_map[related_obj.pk].each { |#{singular_model}| #{singular_model}.associations[:#{as_variable}] = related_obj }
end
end
- end))}
+ end))
+
+ private
+
+ def _#{as_variable}=(#{as_variable})
+ self[:#{as_variable}_id] = (#{as_variable}.pk if #{as_variable})
+ self[:#{as_variable}_type] = (#{as_variable}.class.name if #{as_variable})
+ end
+ }
+ elsif (one_to_many_variable = (options[:one_to_many] or options[:has_many])) && (as_variable = options[:as])
+ singular_one_to_many_variable = one_to_many_variable.to_s.singularize
+ model.class_eval %{
+ associate(:one_to_many, :#{one_to_many_variable}, :key=>:#{as_variable}_id) do |ds|
+ ds.filter(:#{as_variable}_type=>'#{model}')
+ end
+
+ private
+
+ def _add_#{singular_one_to_many_variable}(#{singular_one_to_many_variable})
+ #{singular_one_to_many_variable}.#{as_variable}_id = pk
+ #{singular_one_to_many_variable}.#{as_variable}_type = '#{model}'
+ #{singular_one_to_many_variable}.save
+ end
+ def _remove_#{singular_one_to_many_variable}(#{singular_one_to_many_variable})
+ #{singular_one_to_many_variable}.#{as_variable}_id = nil
+ #{singular_one_to_many_variable}.#{as_variable}_type = nil
+ #{singular_one_to_many_variable}.save
+ end
+ def _remove_all_#{one_to_many_variable}
+ #{singular_one_to_many_variable.capitalize}.filter(:#{as_variable}_id=>pk, :#{as_variable}_type=>'Post').update(:#{as_variable}_id=>nil, :#{as_variable}_type=>nil)
+ end
+ }
end
end
@@ -30,15 +63,4 @@ module ClassMethods
end # Plugins
end # Sequel
-# class Asset < Sequel::Model
-# is :polymorphic, :belongs_to => :attachable
-# end
-#
-# class Post < Sequel::Model
-# is :polymorphic, :has_many => :assets, :as => :attachable
-# end
-#
-# class Note < Sequel::Model
-# is :polymorphic, :has_many => :assets, :as => :attachable
-# end
View
30 spec/sequel-setup.rb
@@ -1,18 +1,36 @@
DB = Sequel.sqlite
-require File.dirname(__FILE__) + '/../lib/sequel_taggable/migration'
-CreateTags.apply(DB, :up)
+class Asset < Sequel::Model
+ set_schema do
+ primary_key :id
+ varchar :name
+ integer :attachable_id
+ varchar :attachable_type
+ end
+
+ is :polymorphic, :belongs_to => :attachable
+
+end
-#DB["select * from sqlite_master"].print
+class Post < Sequel::Model
+ set_schema do
+ primary_key :id
+ varchar :name
+ end
+
+ is :polymorphic, :has_many => :assets, :as => :attachable
+
+end
-class TaggedModel < Sequel::Model
+class Note < Sequel::Model
set_schema do
primary_key :id
varchar :name
end
- is :taggable
+ is :polymorphic, :has_many => :assets, :as => :attachable
+
end
-TaggedModel.create_table!
+[Asset, Post, Note].each {|klass| klass.create_table!}
View
57 spec/sequel_polymorphic/sequel_polymorphic_spec.rb
@@ -1,57 +1,8 @@
require File.dirname(__FILE__) + '/../spec_helper'
-describe Sequel::Plugins::Taggable do
- before do
- @tagged_model = TaggedModel.new
- end
-
- it "should add a .has_tags method to models which include DataMapper::Resource" do
- TaggedModel.should respond_to(:has_tags)
- # AnotherTaggedModel.should respond_to(:has_tags)
- # DefaultTaggedModel.should respond_to(:has_tags)
- # UntaggedModel.should respond_to(:has_tags)
- end
-
- it "should add a .has_tags_on method to models which include DataMapper::Resource" do
- TaggedModel.should respond_to(:has_tags_on)
- # AnotherTaggedModel.should respond_to(:has_tags_on)
- # DefaultTaggedModel.should respond_to(:has_tags_on)
- # UntaggedModel.should respond_to(:has_tags_on)
- end
-
- describe ".has_tags_on" do
- it "should accept an array of context names" do
- class HasTagsOnTestModel < Sequel::Model
- is :taggable
- end
- lambda{HasTagsOnTestModel.has_tags_on(:should, 'not', :raise)}.should_not raise_error(ArgumentError)
- end
-
- it "should create taggable functionality for each of the context names passed" do
- class TestModel < Sequel::Model
- is :taggable
- has_tags_on :pets, 'skills', :tags
- end
- TestModel.should be_taggable
- a = TestModel.new
- a.should be_taggable
- a.should respond_to(:pet_list)
- a.should respond_to(:skill_list)
- a.should respond_to(:tag_list)
- a.should respond_to(:pet_list=)
- a.should respond_to(:skill_list=)
- a.should respond_to(:tag_list=)
- end
- end
-
- describe ".has_tags" do
- it "should raise an error message if someone uses has_tags with an argument list" do
- lambda do
- class TagsOnly < Sequel::Model
- is :taggable
- has_tags :pets, :skills
- end
- end.should raise_error(RuntimeError)
- end
+# Models we have: Post(name), Note(name), Asset(name)
+describe Sequel::Plugins::Polymorphic do
+ it "should do stuff" do
+ true
end
end
View
2  spec/spec_helper.rb
@@ -6,7 +6,7 @@
require 'sequel'
require File.dirname(__FILE__) + '/sequel-setup'
-require File.dirname(__FILE__) + '/../lib/sequel_taggable'
+require File.dirname(__FILE__) + '/../lib/sequel_polymorphic'
Please sign in to comment.
Something went wrong with that request. Please try again.