53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# File 'lib/semantically_taggable/semantically_taggable/collection.rb', line 53
def all_tag_counts(options = {})
options.assert_valid_keys :start_at, :end_at, :conditions, :at_least, :at_most, :order, :limit, :on, :id
scope = {}
options[:conditions] = sanitize_sql(options[:conditions]) if options[:conditions]
scheme_name = options.delete(:on)
start_at_conditions = sanitize_sql(["#{SemanticallyTaggable::Tagging.table_name}.created_at >= ?", options.delete(:start_at)]) if options[:start_at]
end_at_conditions = sanitize_sql(["#{SemanticallyTaggable::Tagging.table_name}.created_at <= ?", options.delete(:end_at)]) if options[:end_at]
taggable_conditions = sanitize_sql(["#{SemanticallyTaggable::Tagging.table_name}.taggable_type = ?", base_class.name])
taggable_conditions << sanitize_sql([" AND #{SemanticallyTaggable::Tagging.table_name}.taggable_id = ?", options.delete(:id)]) if options[:id]
taggable_conditions << sanitize_sql([" AND #{SemanticallyTaggable::Scheme.table_name}.name = ?", scheme_name]) if scheme_name
tagging_conditions = [
taggable_conditions,
start_at_conditions,
end_at_conditions
].compact.reverse
tag_conditions = [
options[:conditions]
].compact.reverse
taggable_join = "INNER JOIN #{table_name} ON #{table_name}.#{primary_key} = #{SemanticallyTaggable::Tagging.table_name}.taggable_id"
taggable_join << " AND #{table_name}.#{inheritance_column} = '#{name}'" unless descends_from_active_record? if scheme_name
taggable_join << " INNER JOIN tags on tags.id = taggings.tag_id "
taggable_join << " INNER JOIN schemes on schemes.id = tags.scheme_id "
end
tagging_joins = [
taggable_join,
scope[:joins]
].compact
tag_joins = [
].compact
tagging_scope = SemanticallyTaggable::Tagging.select("#{SemanticallyTaggable::Tagging.table_name}.tag_id, COUNT(#{SemanticallyTaggable::Tagging.table_name}.tag_id) AS tags_count")
tag_scope = SemanticallyTaggable::Tag.select("#{SemanticallyTaggable::Tag.table_name}.*, #{SemanticallyTaggable::Tagging.table_name}.tags_count AS count").order(options[:order]).limit(options[:limit])
tagging_joins.each { |join| tagging_scope = tagging_scope.joins(join) }
tagging_conditions.each { |condition| tagging_scope = tagging_scope.where(condition) }
tag_joins.each { |join| tag_scope = tag_scope.joins(join) }
tag_conditions.each { |condition| tag_scope = tag_scope.where(condition) }
at_least = sanitize_sql(['tags_count >= ?', options.delete(:at_least)]) if options[:at_least]
at_most = sanitize_sql(['tags_count <= ?', options.delete(:at_most)]) if options[:at_most]
having = ["COUNT(#{SemanticallyTaggable::Tagging.table_name}.tag_id) > 0", at_least, at_most].compact.join(' AND ')
group_columns = "#{SemanticallyTaggable::Tagging.table_name}.tag_id"
scoped_select = "#{table_name}.#{primary_key}"
tagging_scope = tagging_scope.where("taggings.taggable_id IN(#{select(scoped_select).to_sql})").
group(group_columns).
having(having)
tag_scope = tag_scope.joins("JOIN (#{tagging_scope.to_sql}) AS taggings ON taggings.tag_id = tags.id")
tag_scope
end
|