Add recommended tab on proposals and debates index.

This commit is contained in:
taitus
2017-07-28 13:43:01 +02:00
parent 01a41b4706
commit fe3bb7a389
15 changed files with 92 additions and 43 deletions

View File

@@ -8,13 +8,19 @@ module CommentableActions
@resources = @advanced_search_terms.present? ? @resources.filter(@advanced_search_terms) : @resources
@resources = @resources.tagged_with(@tag_filter) if @tag_filter
@resources = @resources.page(params[:page]).for_render.send("sort_by_#{@current_order}")
@resources = if @current_order == "recommended" && current_user.present?
@resources.recommended(current_user).page(params[:page]).send("sort_by_#{@current_order}")
else
@resources.page(params[:page]).for_render.send("sort_by_#{@current_order}")
end
index_customization if index_customization.present?
@tag_cloud = tag_cloud
@banners = Banner.with_active
set_resource_votes(@resources)
set_resources_instance
end

View File

@@ -10,7 +10,7 @@ class DebatesController < ApplicationController
invisible_captcha only: [:create, :update], honeypot: :subtitle
has_orders %w{hot_score confidence_score created_at relevance}, only: :index
has_orders ->(c) { Debate.debates_orders(c.current_user) }, only: :index
has_orders %w{most_voted newest oldest}, only: :show
load_and_authorize_resource

View File

@@ -9,7 +9,7 @@ class ProposalsController < ApplicationController
invisible_captcha only: [:create, :update], honeypot: :subtitle
has_orders %w{hot_score confidence_score created_at relevance archival_date}, only: :index
has_orders ->(c) { Proposal.proposals_orders(c.current_user) }, only: :index
has_orders %w{most_voted newest oldest}, only: :show
load_and_authorize_resource

View File

@@ -1,5 +1,6 @@
class WelcomeController < ApplicationController
skip_authorization_check
before_action :set_user_recommendations, only: :index, if: :current_user
layout "devise", only: [:welcome, :verification]
@@ -13,4 +14,11 @@ class WelcomeController < ApplicationController
redirect_to verification_path if signed_in?
end
private
def set_user_recommendations
@recommended_debates = Debate.recommended(current_user).limit(3)
@recommended_proposals = Proposal.recommended(current_user).limit(3)
end
end

View File

@@ -37,14 +37,27 @@ class Debate < ActiveRecord::Base
scope :sort_by_random, -> { reorder("RANDOM()") }
scope :sort_by_relevance, -> { all }
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
scope :sort_by_recommended, -> { order(cached_votes_total: :desc) }
scope :last_week, -> { where("created_at >= ?", 7.days.ago)}
scope :featured, -> { where("featured_at is not null")}
scope :public_for_api, -> { all }
# Ahoy setup
visitable # Ahoy will automatically assign visit_id on create
attr_accessor :link_required
def self.recommended(user)
debates_list = where("author_id != ?", user.id)
#same as "with_tagged(user.interests, any: true)"
debates_list_with_tagged = debates_list.joins(:tags).where('taggings.taggable_type = ?', self.name).where('tags.name IN (?)', user.interests)
if debates_list_with_tagged.any?
debates_list = debates_list_with_tagged
end
debates_list
end
def searchable_values
{ title => 'A',
author.username => 'B',
@@ -135,4 +148,9 @@ class Debate < ActiveRecord::Base
featured_at.present?
end
def self.debates_orders(user)
orders = %w{hot_score confidence_score created_at relevance}
orders << "recommended" if user.present?
orders
end
end

View File

@@ -48,6 +48,7 @@ class Proposal < ActiveRecord::Base
scope :sort_by_relevance, -> { all }
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
scope :sort_by_archival_date, -> { archived.sort_by_confidence_score }
scope :sort_by_recommended, -> { order(cached_votes_up: :desc) }
scope :archived, -> { where("proposals.created_at <= ?", Setting["months_to_archive_proposals"].to_i.months.ago) }
scope :not_archived, -> { where("proposals.created_at > ?", Setting["months_to_archive_proposals"].to_i.months.ago) }
scope :last_week, -> { where("proposals.created_at >= ?", 7.days.ago)}
@@ -56,6 +57,18 @@ class Proposal < ActiveRecord::Base
scope :successful, -> { where("cached_votes_up >= ?", Proposal.votes_needed_for_success) }
scope :public_for_api, -> { all }
def self.recommended(user)
proposals_list = where("author_id != ?", user.id)
proposals_list_with_tagged = proposals_list.joins(:tags).where('taggings.taggable_type = ?', self.name)
.where('tags.name IN (?)', user.interests)
if proposals_list_with_tagged.any?
followed_proposals_ids = Proposal.followed_by_user(user).pluck(:id)
proposals_list = proposals_list_with_tagged.where("proposals.id NOT IN (?)", followed_proposals_ids)
end
proposals_list
end
def to_param
"#{id}-#{title}".parameterize
end
@@ -175,6 +188,12 @@ class Proposal < ActiveRecord::Base
(voters + followers).uniq
end
def self.proposals_orders(user)
orders = %w{hot_score confidence_score created_at relevance archival_date}
orders << "recommended" if user.present?
orders
end
protected
def set_responsible_name

View File

@@ -313,29 +313,6 @@ class User < ActiveRecord::Base
follows.map{|follow| follow.followable.tags.map(&:name)}.flatten.compact.uniq
end
def recommended_debates
debates_list = Debate.where("author_id != ?", self)
debates_list_with_tagged = debates_list.tagged_with(interests, any: true)
if interests.any? && debates_list_with_tagged.any?
debates_list = debates_list_with_tagged
end
debates_list.order("cached_votes_total DESC").limit(3)
end
def recommended_proposals
proposals_list = Proposal.where("author_id != ?", id)
proposals_list_with_tagged = proposals_list.tagged_with(interests, any: true)
if interests.any? && proposals_list_with_tagged.any?
followed_proposals_ids = Proposal.followed_by_user(self).pluck(:id)
proposals_list = proposals_list_with_tagged.where("id NOT IN (?)", followed_proposals_ids)
end
proposals_list.order("cached_votes_up DESC").limit(3)
end
private
def clean_document_number

View File

@@ -53,7 +53,7 @@
<div class="show-for-small-only">
<%= link_to t("debates.index.start_debate"), new_debate_path, class: 'button expanded' %>
</div>
<%= render @debates %>
<%= paginate @debates %>
</div>

View File

@@ -11,6 +11,7 @@
image_version: nil,
image_default: "https://dummyimage.com/600x400/000/fff",
carousel_size: carousel_size %>
<%= link_to "todos los debates recomendados", debates_path(order: "recommended") %>
<% end %>
<% if recommended_proposals.any? %>
@@ -21,6 +22,7 @@
image_version: nil,
image_default: "https://dummyimage.com/600x400/000/fff",
carousel_size: carousel_size %>
<%= link_to "todos las propuestas recomendados", proposals_path(order: "recommended") %>
<% end %>
</div>
</div>

View File

@@ -23,20 +23,12 @@
</div>
</div>
<% if current_user.present? && feature?(:recommendeds) %>
<% recommended_debates = current_user.recommended_debates %>
<% recommended_proposals = current_user.recommended_proposals %>
<% if display_recommendeds(recommended_debates, recommended_proposals) %>
<%= render "recommended", recommended_debates: recommended_debates,
recommended_proposals: recommended_proposals %>
<% end %>
<% if feature?("user.recommendations") && (@recommended_debates.present? || @recommended_proposals.present?) %>
<%= render "recommended",
recommended_debates: @recommended_debates,
recommended_proposals: @recommended_proposals %>
<% end %>
<% cache [locale_and_user_status, @featured_debates, @featured_proposals, 'featured'] do %>
<main>
<div class="highlight small-12 column text-center">

View File

@@ -39,7 +39,8 @@ en:
spending_proposal_features:
voting_allowed: Voting on investment projects
legislation: Legislation
recommendeds: Recommendeds
user:
recommendations: Recommendeds
mailer_from_name: Origin email name
mailer_from_address: Origin email address
meta_description: "Site description (SEO)"

View File

@@ -39,7 +39,8 @@ es:
spending_proposal_features:
voting_allowed: Votaciones sobre propuestas de inversión
legislation: Legislación
recommendeds: Recomendaciones
user:
recommendations: Recomendaciones
mailer_from_name: Nombre email remitente
mailer_from_address: Dirección email remitente
meta_description: "Descripción del sitio (SEO)"

View File

@@ -36,7 +36,7 @@ Setting.create(key: 'feature.facebook_login', value: "true")
Setting.create(key: 'feature.google_login', value: "true")
Setting.create(key: 'feature.signature_sheets', value: "true")
Setting.create(key: 'feature.legislation', value: "true")
Setting.create(key: 'feature.recommendeds', value: "true")
Setting.create(key: 'feature.user.recommendations', value: "true")
Setting.create(key: 'per_page_code_head', value: "")
Setting.create(key: 'per_page_code_body', value: "")
Setting.create(key: 'comments_body_max_length', value: '1000')

View File

@@ -79,7 +79,7 @@ Setting['feature.public_stats'] = true
Setting['feature.budgets'] = true
Setting['feature.signature_sheets'] = true
Setting['feature.legislation'] = true
Setting['feature.recommendeds'] = nil
Setting['feature.user.recommendations'] = nil
# Spending proposals feature flags
Setting['feature.spending_proposal_features.voting_allowed'] = nil

View File

@@ -28,6 +28,14 @@ feature "Home" do
feature "Recommended" do
background do
Setting['feature.user.recommendations'] = true
end
after do
Setting['feature.user.recommendations'] = nil
end
scenario 'Display recommended section' do
debate = create(:debate)
@@ -36,6 +44,23 @@ feature "Home" do
expect(page).to have_content "Recommendations that may interest you"
end
scenario 'Display recommended section when feature flag recommended is active' do
debate = create(:debate)
visit root_path
expect(page).to have_content "Recommendations that may interest you"
end
scenario 'Not display recommended section when feature flag recommended is not active' do
debate = create(:debate)
Setting['feature.user.recommendations'] = false
visit root_path
expect(page).not_to have_content "Recommendations that may interest you"
end
scenario 'Display debates' do
debate = create(:debate)