Sha256: ad0ee45beae0f66121b97182fee7eb05b2c5cb4a5dc3e59df9560a312372843c
Contents?: true
Size: 1.6 KB
Versions: 1
Compression:
Stored size: 1.6 KB
Contents
require "polymorph/relation" require "byebug" module Polymorph module Methods def polymorph(method_name, through:, source_types:, fields: [:id], through_class: through.to_s.singularize.camelize.constantize, source_column: method_name.to_s.singularize, source_type: "#{source_column}_type") define_method method_name, -> { query = send(through).select([ source_types.map { |t| "#{t}.*" }, source_types.product(fields).map { |a| "#{a[0]}.#{a[1]} AS #{a[0].to_s.singularize}_#{a[1]}" }, "#{through}.#{source_column}_type", "'true'::boolean as polymorph_query" ].flatten.join(', ')) source_types.each do |type| query = query.joins(%{ LEFT OUTER JOIN #{type} ON #{type}.id = #{through}.#{source_column}_id AND '#{type.to_s.singularize.camelize}' = #{through}.#{source_type} }) end Polymorph::Relation.new(query, fields: fields, source_types: source_types) } through_class.define_singleton_method :instantiate, ->(attrs, column_types) { super(attrs, column_types).tap do |record| transfer_fields = fields.map { |field| [field, attrs["#{attrs[source_type].downcase}_#{field}"]] }.to_h record.assign_attributes(transfer_fields) end } through_class.define_singleton_method :discriminate_class_for_record, ->(attributes) { return super(attributes) unless attributes['polymorph_query'].present? attributes["#{source_column}_type"].camelize.constantize } end end end
Version data entries
1 entries across 1 versions & 1 rubygems
Version | Path |
---|---|
activerecord-polymorph-0.1.0 | lib/polymorph/methods.rb |