class Join < ActiveRecord::Base def Join.for *args desc = args.shift src, dst, *ignored = desc.to_a.flatten src_options = (args.shift || {}).to_options dst_options = (args.shift || {}).to_options const = "#{ src }_#{ dst }".camelize unless const_defined?(const) join_model = Class.new(Join) const_set const, join_model join_model.module_eval do belongs_to src.to_s.to_sym, src_options.reverse_merge(:foreign_key => :src) belongs_to dst.to_s.to_sym, dst_options.reverse_merge(:foreign_key => :dst) end end "::Join::#{ const }" end class Migration < ActiveRecord::Migration def self.up create_table :joins do |t| t.string :type # sti t.integer :src t.integer :dst t.timestamps end add_index :joins, [:type] add_index :joins, [:src] add_index :joins, [:dst] add_index :joins, [:src, :dst], :unique => true end def self.down remove_index :joins, [:src, :dst] remove_index :joins, [:dst] remove_index :joins, [:src] remove_index :joins, [:type] drop_table :joins end end end