lib/writefully/taxon.rb in writefully-0.4.10 vs lib/writefully/taxon.rb in writefully-0.5.0
- old
+ new
@@ -1,7 +1,15 @@
module Writefully
- Taxon = Struct.new(:incoming, :existing, :type) do
+ class Taxon
+ attr_reader :incoming, :existing, :type
+
+ def initialize(incoming, existing, type)
+ @incoming = incoming
+ @existing = existing
+ @type = type
+ end
+
def non_existing
get_difference.map { |token| Tag.new(build_attributes(token)) }
end
def selector
@@ -21,8 +29,51 @@
.merge({ name: token, slug: token.parameterize })
end
def parameterized items
items.map { |t| t.parameterize }
+ end
+
+ class EagerLoader
+ attr_reader :tags, :taggings, :resource
+
+ def initialize(klass)
+ @tags = Tag.arel_table
+ @taggings = Tagging.arel_table
+ @resource = klass.arel_table
+ end
+
+ def build *types
+ [resource[Arel.star]] << types.map { |type| array_of_taxonomy_hstores_for(type) }
+ end
+
+ private
+
+ def array_of_taxonomy_hstores_for type
+ Arel::Nodes::NamedFunction.new('ARRAY', [hstore_for_taxon(type)]).as("all_#{type}")
+ end
+
+ def hstore_for_taxon type
+ tags.project(Arel.sql('hstore(taxon)')).from(taxons_for_resource(type))
+ end
+
+ def taxons_for_resource type
+ Tag.joins(:taggings).arel.where(tags_by_type(type))
+ .where(taggings_by_resource).as('taxon')
+ end
+
+ def tags_by_type type
+ tags[:type].eq(calculate_type(type))
+ end
+
+ def taggings_by_resource
+ # we use post_id for now but we should
+ # make it a polymorphic association later
+ taggings[:post_id].eq(resource[:id])
+ end
+
+ def calculate_type type
+ type == :tags ? nil : type.to_s.classify
+ end
end
end
end
\ No newline at end of file