Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # TODO: add a check to make sure a relationship doens't already exist before insert
- module ActiveRecord
- module Associations # :nodoc:
- module ClassMethods
- def has_many_polymorphs(association_id, options={})
- pjoin = options[:polymorphic_join_table]
- #from polymorphic column field names
- pfrom = {:id_label => (options[:polymorphic_from].to_s + '_id').to_sym,:type_label => (options[:polymorphic_from].to_s + '_type').to_sym, :type => self}
- #to polymorphic column field names
- pto = {:id_label => (options[:polymorphic_to].to_s + '_id').to_sym,:type_label => (options[:polymorphic_to].to_s + '_type').to_sym,:type => association_id.to_s.classify.to_s, :table => association_id}
- single_direction_finder = "SELECT #{pto[:table]}.* " +
- "FROM #{pto[:table]} INNER JOIN #{pjoin} ON #{pto[:table]}.id = #{pjoin}.#{pto[:id_label]} " +
- "WHERE #{pjoin}.#{pfrom[:id_label]} =" + ' #{id} ' +
- "AND #{pjoin}.#{pfrom[:type_label]} = '#{pfrom[:type]}' AND #{pjoin}.#{pto[:type_label]} = '#{pto[:type]}'"
- bidirectional_finder = "SELECT #{pto[:table]}.* " +
- "FROM #{pto[:table]} INNER JOIN #{pjoin} ON " +
- "(#{pto[:table]}.id = #{pjoin}.#{pto[:id_label]} AND #{pjoin}.#{pfrom[:type_label]} = '#{pfrom[:type]}') OR " +
- "(#{pto[:table]}.id = #{pjoin}.#{pfrom[:id_label]} AND #{pjoin}.#{pto[:type_label]} = '#{pfrom[:type]}') " +
- "WHERE " +
- "(#{pjoin}.#{pfrom[:id_label]} =" + ' #{id} ' + " AND #{pjoin}.#{pfrom[:type_label]} = '#{pfrom[:type]}' AND #{pjoin}.#{pto[:type_label]} = '#{pto[:type]}') " +
- "OR " +
- "(#{pjoin}.#{pto[:id_label]} =" + ' #{id} ' + " AND #{pjoin}.#{pto[:type_label]} = '#{pfrom[:type]}' AND #{pjoin}.#{pfrom[:type_label]} = '#{pto[:type]}') "
- class_eval do
- has_and_belongs_to_many pto[:table],
- {:join_table => pjoin,
- :foreign_key => pfrom[:id_label],
- :association_foreign_key => pto[:id_label],
- :finder_sql => (options[:bidirectional].blank? ? single_direction_finder : bidirectional_finder),
- :insert_sql =>
- "INSERT INTO #{pjoin} (`#{pfrom[:id_label]}`, `#{pfrom[:type_label]}`, `#{pto[:id_label]}`, `#{pto[:type_label]}`) " +
- 'VALUES (#{id}, ' + "'#{pfrom[:type]}', " + '#{record.id}, ' + "'#{pto[:type]}')",
- :delete_sql =>
- "DELETE FROM #{pjoin} WHERE #{pfrom[:id_label]} = " +
- '#{id}' + " AND #{pfrom[:type_label]} = '#{pfrom[:type]}' AND #{pto[:id_label]} = " +
- '#{record.id}' + " AND #{pto[:type_label]} = '#{pto[:type]}'"
- }
- end #end clas_eval
- end #end def
- end #end classmethods
- end #associatioins
- end #end active record
Add Comment
Please, Sign In to add comment