Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Ruby
tree: 945f8dfb33

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib
spec
LICENSE
README
Rakefile
TODO

README

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, :as => :attachable
end

voila!
Something went wrong with that request. Please try again.