@@ -73,7 +73,7 @@ module CommentableActions
|
||||
end
|
||||
|
||||
def tag_cloud
|
||||
resource_model.last_week.tag_counts.order("#{resource_name.pluralize}_count": :desc, name: :asc).limit(5)
|
||||
TagCloud.new(resource_model, params[:search])
|
||||
end
|
||||
|
||||
def load_geozones
|
||||
|
||||
@@ -3,26 +3,12 @@ module TagsHelper
|
||||
def taggable_path(taggable_type, tag_name)
|
||||
case taggable_type
|
||||
when 'debate'
|
||||
debates_path(tag: tag_name)
|
||||
debates_path(search: tag_name)
|
||||
when 'proposal'
|
||||
proposals_path(tag: tag_name)
|
||||
proposals_path(search: tag_name)
|
||||
else
|
||||
'#'
|
||||
end
|
||||
end
|
||||
|
||||
def taggable_counter_field(taggable_type)
|
||||
"#{taggable_type.underscore.pluralize}_count"
|
||||
end
|
||||
|
||||
def tag_cloud(tags, classes, counter_field = :taggings_count)
|
||||
return [] if tags.empty?
|
||||
|
||||
max_count = tags.sort_by(&counter_field).last.send(counter_field).to_f
|
||||
|
||||
tags.each do |tag|
|
||||
index = ((tag.send(counter_field) / max_count) * (classes.size - 1))
|
||||
yield tag, classes[index.nan? ? 0 : index.round]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
38
app/models/tag_cloud.rb
Normal file
38
app/models/tag_cloud.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
class TagCloud
|
||||
|
||||
attr_accessor :resource_model, :scope
|
||||
|
||||
def initialize(resource_model, scope=nil)
|
||||
@resource_model = resource_model
|
||||
@scope = scope
|
||||
end
|
||||
|
||||
def tags
|
||||
resource_model_scoped.
|
||||
last_week.tag_counts.
|
||||
where("lower(name) NOT IN (?)", category_names + geozone_names + default_blacklist).
|
||||
order("#{table_name}_count": :desc, name: :asc).
|
||||
limit(10)
|
||||
end
|
||||
|
||||
def category_names
|
||||
ActsAsTaggableOn::Tag.where("kind = 'category'").map {|tag| tag.name.downcase }
|
||||
end
|
||||
|
||||
def geozone_names
|
||||
Geozone.all.map {|geozone| geozone.name.downcase }
|
||||
end
|
||||
|
||||
def resource_model_scoped
|
||||
scope && resource_model == Proposal ? resource_model.search(scope) : resource_model
|
||||
end
|
||||
|
||||
def default_blacklist
|
||||
['']
|
||||
end
|
||||
|
||||
def table_name
|
||||
resource_model.to_s.downcase.pluralize
|
||||
end
|
||||
|
||||
end
|
||||
@@ -3,10 +3,9 @@
|
||||
<h3 class="sidebar-title"><%= t("shared.tags_cloud.tags") %></h3>
|
||||
<br>
|
||||
|
||||
<% tag_cloud @tag_cloud, %w[s m l] do |tag, css_class| %>
|
||||
<%= link_to taggable_path(taggable, tag.name), class: css_class do %>
|
||||
<%= tag.name %>
|
||||
(<%= tag.send(taggable_counter_field(taggable)) %>)
|
||||
<% @tag_cloud.tags.each do |tag| %>
|
||||
<%= link_to taggable_path(taggable, tag.name) do %>
|
||||
<span class="tag"><%= tag.name %></span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -54,22 +54,6 @@ feature 'Tags' do
|
||||
expect(page).to have_content "Hacienda"
|
||||
end
|
||||
|
||||
scenario 'Tag Cloud' do
|
||||
1.times { create(:debate, tag_list: 'Medio Ambiente') }
|
||||
5.times { create(:debate, tag_list: 'Corrupción') }
|
||||
5.times { create(:debate, tag_list: 'Educación') }
|
||||
10.times { create(:debate, tag_list: 'Economía') }
|
||||
|
||||
visit debates_path
|
||||
|
||||
within(:css, "#tag-cloud") do
|
||||
expect(page.find("a:eq(1)")).to have_content("Economía (10)")
|
||||
expect(page.find("a:eq(2)")).to have_content("Corrupción (5)")
|
||||
expect(page.find("a:eq(3)")).to have_content("Educación (5)")
|
||||
expect(page.find("a:eq(4)")).to have_content("Medio Ambiente (1)")
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'Create' do
|
||||
user = create(:user)
|
||||
login_as(user)
|
||||
@@ -141,4 +125,81 @@ feature 'Tags' do
|
||||
expect(page).to_not have_content 'Economía'
|
||||
end
|
||||
|
||||
context 'Tag cloud' do
|
||||
|
||||
scenario 'Proposals' do
|
||||
earth = create(:proposal, tag_list: 'Medio Ambiente')
|
||||
money = create(:proposal, tag_list: 'Economía')
|
||||
|
||||
visit proposals_path
|
||||
|
||||
within "#tag-cloud" do
|
||||
expect(page).to have_content "Medio Ambiente"
|
||||
expect(page).to have_content "Economía"
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'Debates' do
|
||||
earth = create(:debate, tag_list: 'Medio Ambiente')
|
||||
money = create(:debate, tag_list: 'Economía')
|
||||
|
||||
visit debates_path
|
||||
|
||||
within "#tag-cloud" do
|
||||
expect(page).to have_content "Medio Ambiente"
|
||||
expect(page).to have_content "Economía"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "scoped by category" do
|
||||
create(:tag, kind: 'category', name: 'Medio Ambiente')
|
||||
create(:tag, kind: 'category', name: 'Economía')
|
||||
|
||||
earth = create(:proposal, tag_list: 'Medio Ambiente, Agua')
|
||||
money = create(:proposal, tag_list: 'Economía, Corrupción')
|
||||
|
||||
visit proposals_path(search: 'Economía')
|
||||
|
||||
within "#tag-cloud" do
|
||||
expect(page).to have_css(".tag", count: 1)
|
||||
expect(page).to have_content "Corrupción"
|
||||
expect(page).to_not have_content "Economía"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "scoped by district" do
|
||||
create(:geozone, name: 'Madrid')
|
||||
create(:geozone, name: 'Barcelona')
|
||||
|
||||
earth = create(:proposal, tag_list: 'Madrid, Agua')
|
||||
money = create(:proposal, tag_list: 'Barcelona, Playa')
|
||||
|
||||
visit proposals_path(search: 'Barcelona')
|
||||
|
||||
within "#tag-cloud" do
|
||||
expect(page).to have_css(".tag", count: 1)
|
||||
expect(page).to have_content "Playa"
|
||||
expect(page).to_not have_content "Agua"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "tag links" do
|
||||
proposal1 = create(:proposal, tag_list: 'Medio Ambiente')
|
||||
proposal2 = create(:proposal, tag_list: 'Medio Ambiente')
|
||||
proposal3 = create(:proposal, tag_list: 'Economía')
|
||||
|
||||
visit proposals_path
|
||||
|
||||
within "#tag-cloud" do
|
||||
click_link "Medio Ambiente"
|
||||
end
|
||||
|
||||
expect(page).to have_css ".proposal", count: 2
|
||||
expect(page).to have_content proposal1.title
|
||||
expect(page).to have_content proposal2.title
|
||||
expect(page).to_not have_content proposal3.title
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
116
spec/models/tag_cloud_spec.rb
Normal file
116
spec/models/tag_cloud_spec.rb
Normal file
@@ -0,0 +1,116 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe TagCloud do
|
||||
|
||||
describe "#tags" do
|
||||
|
||||
it "returns proposal tags" do
|
||||
create(:proposal, tag_list: 'participation')
|
||||
create(:debate, tag_list: 'world hunger')
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal)
|
||||
|
||||
expect(tag_names(tag_cloud)).to contain_exactly('participation')
|
||||
end
|
||||
|
||||
it "returns debate tags" do
|
||||
create(:proposal, tag_list: 'participation')
|
||||
create(:debate, tag_list: 'world hunger')
|
||||
|
||||
tag_cloud = TagCloud.new(Debate)
|
||||
|
||||
expect(tag_names(tag_cloud)).to contain_exactly('world hunger')
|
||||
end
|
||||
|
||||
it "returns tags from last week" do
|
||||
create(:proposal, tag_list: 'participation', created_at: 1.day.ago)
|
||||
create(:proposal, tag_list: 'corruption', created_at: 2.weeks.ago)
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal)
|
||||
|
||||
expect(tag_names(tag_cloud)).to contain_exactly('participation')
|
||||
end
|
||||
|
||||
it "does not return category tags" do
|
||||
create(:tag, kind: 'category', name: 'Education')
|
||||
create(:tag, kind: 'category', name: 'Participation')
|
||||
|
||||
create(:proposal, tag_list: 'education, parks')
|
||||
create(:proposal, tag_list: 'participation, water')
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal)
|
||||
|
||||
expect(tag_names(tag_cloud)).to contain_exactly('parks', 'water')
|
||||
end
|
||||
|
||||
it "does not return geozone names" do
|
||||
create(:geozone, name: 'California')
|
||||
create(:geozone, name: 'New York')
|
||||
|
||||
create(:proposal, tag_list: 'parks, California')
|
||||
create(:proposal, tag_list: 'water, New York')
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal)
|
||||
|
||||
expect(tag_names(tag_cloud)).to contain_exactly('parks', 'water')
|
||||
end
|
||||
|
||||
it "returns tags scoped by category" do
|
||||
create(:tag, kind: 'category', name: 'Education')
|
||||
create(:tag, kind: 'category', name: 'Participation')
|
||||
|
||||
create(:proposal, tag_list: 'education, parks')
|
||||
create(:proposal, tag_list: 'participation, water')
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal, 'Education')
|
||||
|
||||
expect(tag_names(tag_cloud)).to contain_exactly('parks')
|
||||
end
|
||||
|
||||
it "returns tags scoped by geozone" do
|
||||
create(:geozone, name: 'California')
|
||||
create(:geozone, name: 'New York')
|
||||
|
||||
create(:proposal, tag_list: 'parks, California')
|
||||
create(:proposal, tag_list: 'water, New York')
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal, 'California')
|
||||
|
||||
expect(tag_names(tag_cloud)).to contain_exactly('parks')
|
||||
end
|
||||
|
||||
xit "returns tags scoped by category for debates"
|
||||
xit "returns tags scoped by geozone for debates"
|
||||
|
||||
it "orders tags by count" do
|
||||
3.times { create(:proposal, tag_list: 'participation') }
|
||||
create(:proposal, tag_list: 'corruption')
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal)
|
||||
|
||||
expect(tag_names(tag_cloud).first).to eq 'participation'
|
||||
expect(tag_names(tag_cloud).second).to eq 'corruption'
|
||||
end
|
||||
|
||||
it "orders tags by count and then by name" do
|
||||
3.times { create(:proposal, tag_list: 'participation') }
|
||||
3.times { create(:proposal, tag_list: 'health') }
|
||||
create(:proposal, tag_list: 'corruption')
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal)
|
||||
|
||||
expect(tag_names(tag_cloud).first).to eq 'health'
|
||||
expect(tag_names(tag_cloud).second).to eq 'participation'
|
||||
expect(tag_names(tag_cloud).third).to eq 'corruption'
|
||||
end
|
||||
|
||||
it "returns a maximum of 10 tags" do
|
||||
12.times { |i| create(:proposal, tag_list: "Tag #{i}") }
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal)
|
||||
|
||||
expect(tag_names(tag_cloud).count).to eq(10)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -175,4 +175,8 @@ module CommonActions
|
||||
create(:debate, :with_confidence_score, cached_votes_up: 80)]
|
||||
end
|
||||
|
||||
def tag_names(tag_cloud)
|
||||
tag_cloud.tags.map(&:name)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user