Merge pull request #2311 from consul/2299-budget_investments_related_content

Budget investments related content
This commit is contained in:
BertoCQ
2018-01-15 20:02:34 +01:00
committed by GitHub
12 changed files with 41 additions and 21 deletions

View File

@@ -41,6 +41,7 @@ module Budgets
def show def show
@commentable = @investment @commentable = @investment
@comment_tree = CommentTree.new(@commentable, params[:page], @current_order) @comment_tree = CommentTree.new(@commentable, params[:page], @current_order)
@related_contents = Kaminari.paginate_array(@investment.relationed_contents).page(params[:page]).per(5)
set_comment_flags(@comment_tree.comments) set_comment_flags(@comment_tree.comments)
load_investment_votes(@investment) load_investment_votes(@investment)
@investment_ids = [@investment.id] @investment_ids = [@investment.id]

View File

@@ -12,7 +12,7 @@ class RelatedContentsController < ApplicationController
flash[:error] = t('related_content.error', url: Setting['url']) flash[:error] = t('related_content.error', url: Setting['url'])
end end
redirect_to @relationable redirect_to @relationable.url
end end
def score_positive def score_positive
@@ -44,8 +44,9 @@ class RelatedContentsController < ApplicationController
if valid_url? if valid_url?
url = params[:url] url = params[:url]
related_klass = url.match(/\/(#{RelatedContent::RELATIONABLE_MODELS.join("|")})\//)[0].delete("/") related_klass = url.scan(/\/(#{RelatedContent::RELATIONABLE_MODELS.join("|")})\//)
related_id = url.match(/\/[0-9]+/)[0].delete("/") .flatten.map { |i| i.to_s.singularize.camelize }.join("::")
related_id = url.match(/\/(\d+)(?!.*\/\d)/)[1]
@related = related_klass.singularize.camelize.constantize.find_by(id: related_id) @related = related_klass.singularize.camelize.constantize.find_by(id: related_id)
end end

View File

@@ -1,6 +1,7 @@
class Budget class Budget
class Investment < ActiveRecord::Base class Investment < ActiveRecord::Base
require 'csv' require 'csv'
include Rails.application.routes.url_helpers
include Measurable include Measurable
include Sanitizable include Sanitizable
include Taggable include Taggable
@@ -79,6 +80,10 @@ class Budget
before_validation :set_responsible_name before_validation :set_responsible_name
before_validation :set_denormalized_ids before_validation :set_denormalized_ids
def url
budget_investment_path(budget, self)
end
def self.filter_params(params) def self.filter_params(params)
params.select{|x, _| %w{heading_id group_id administrator_id tag_name valuator_id}.include? x.to_s } params.select{|x, _| %w{heading_id group_id administrator_id tag_name valuator_id}.include? x.to_s }
end end

View File

@@ -1,5 +1,6 @@
require 'numeric' require 'numeric'
class Debate < ActiveRecord::Base class Debate < ActiveRecord::Base
include Rails.application.routes.url_helpers
include Flaggable include Flaggable
include Taggable include Taggable
include Conflictable include Conflictable
@@ -49,6 +50,10 @@ class Debate < ActiveRecord::Base
attr_accessor :link_required attr_accessor :link_required
def url
debate_path(self)
end
def self.recommendations(user) def self.recommendations(user)
tagged_with(user.interests, any: true) tagged_with(user.interests, any: true)
.where("author_id != ?", user.id) .where("author_id != ?", user.id)

View File

@@ -1,4 +1,5 @@
class Proposal < ActiveRecord::Base class Proposal < ActiveRecord::Base
include Rails.application.routes.url_helpers
include Flaggable include Flaggable
include Taggable include Taggable
include Conflictable include Conflictable
@@ -71,6 +72,10 @@ class Proposal < ActiveRecord::Base
scope :public_for_api, -> { all } scope :public_for_api, -> { all }
scope :not_supported_by_user, ->(user) { where.not(id: user.find_voted_items(votable_type: "Proposal").compact.map(&:id)) } scope :not_supported_by_user, ->(user) { where.not(id: user.find_voted_items(votable_type: "Proposal").compact.map(&:id)) }
def url
proposal_path(self)
end
def self.recommendations(user) def self.recommendations(user)
tagged_with(user.interests, any: true) tagged_with(user.interests, any: true)
.where("author_id != ?", user.id) .where("author_id != ?", user.id)

View File

@@ -1,6 +1,6 @@
class RelatedContent < ActiveRecord::Base class RelatedContent < ActiveRecord::Base
RELATED_CONTENT_SCORE_THRESHOLD = Setting['related_content_score_threshold'].to_f RELATED_CONTENT_SCORE_THRESHOLD = Setting['related_content_score_threshold'].to_f
RELATIONABLE_MODELS = %w{proposals debates}.freeze RELATIONABLE_MODELS = %w{proposals debates budgets investments}.freeze
acts_as_paranoid column: :hidden_at acts_as_paranoid column: :hidden_at
include ActsAsParanoidAliases include ActsAsParanoidAliases

View File

@@ -69,6 +69,7 @@
<p><%= investment.price_explanation %></p> <p><%= investment.price_explanation %></p>
<% end %> <% end %>
<%= render 'relationable/related_content', relationable: @investment %>
</div> </div>
<aside class="small-12 medium-3 column"> <aside class="small-12 medium-3 column">

View File

@@ -7,10 +7,9 @@
<%= render 'relationable/score', related: related_content %> <%= render 'relationable/score', related: related_content %>
</span> </span>
<% end %> <% end %>
<span class="related-content-title"><%= t("related_content.content_title.#{related.model_name.singular}") %></span><br>
<span class="related-content-title"><%= t("related_content.content_title.#{related.class.name.downcase}") %></span><br>
<h3 class="inline-block"> <h3 class="inline-block">
<%= link_to related.title, eval("#{related.class.name.downcase}_path(related)") %> <%= link_to related.title, related.url %>
</h3> </h3>
</li> </li>
<% end %> <% end %>

View File

@@ -827,3 +827,4 @@ en:
content_title: content_title:
proposal: "Proposal" proposal: "Proposal"
debate: "Debate" debate: "Debate"
budget_investment: "Budget investment"

View File

@@ -826,3 +826,4 @@ es:
content_title: content_title:
proposal: "Propuesta" proposal: "Propuesta"
debate: "Debate" debate: "Debate"
budget_investment: "Propuesta de inversión"

View File

@@ -20,6 +20,7 @@ feature 'Budget Investments' do
context "Concerns" do context "Concerns" do
it_behaves_like 'notifiable in-app', Budget::Investment it_behaves_like 'notifiable in-app', Budget::Investment
it_behaves_like 'relationable', Budget::Investment
end end
scenario 'Index' do scenario 'Index' do

View File

@@ -1,39 +1,39 @@
shared_examples "relationable" do |relationable_model_name| shared_examples "relationable" do |relationable_model_name|
let(:relationable) { create(relationable_model_name.name.downcase.to_sym) } let(:relationable) { create(relationable_model_name.name.parameterize('_').to_sym) }
let(:related1) { create([:proposal, :debate].sample) } let(:related1) { create([:proposal, :debate, :budget_investment].sample) }
let(:related2) { create([:proposal, :debate].sample) } let(:related2) { create([:proposal, :debate, :budget_investment].sample) }
let(:user) { create(:user) } let(:user) { create(:user) }
scenario 'related contents are listed' do scenario 'related contents are listed' do
related_content = create(:related_content, parent_relationable: relationable, child_relationable: related1, author: build(:user)) related_content = create(:related_content, parent_relationable: relationable, child_relationable: related1, author: build(:user))
visit send("#{relationable.class.name.downcase}_path", relationable) visit relationable.url
within("#related-content-list") do within("#related-content-list") do
expect(page).to have_content(related1.title) expect(page).to have_content(related1.title)
end end
visit send("#{related1.class.name.downcase}_path", related1) visit related1.url
within("#related-content-list") do within("#related-content-list") do
expect(page).to have_content(relationable.title) expect(page).to have_content(relationable.title)
end end
end end
scenario 'related contents list is not rendered if there are no relations' do scenario 'related contents list is not rendered if there are no relations' do
visit send("#{relationable.class.name.downcase}_path", relationable) visit relationable.url
expect(page).not_to have_css("#related-content-list") expect(page).not_to have_css("#related-content-list")
end end
scenario 'related contents can be added' do scenario 'related contents can be added' do
login_as(user) login_as(user)
visit send("#{relationable.class.name.downcase}_path", relationable) visit relationable.url
expect(page).to have_selector('#related_content', visible: false) expect(page).to have_selector('#related_content', visible: false)
click_on("Add related content") click_on("Add related content")
expect(page).to have_selector('#related_content', visible: true) expect(page).to have_selector('#related_content', visible: true)
within("#related_content") do within("#related_content") do
fill_in 'url', with: "#{Setting['url']}/#{related1.class.name.downcase.pluralize}/#{related1.to_param}" fill_in 'url', with: "#{Setting['url'] + related1.url}"
click_button "Add" click_button "Add"
end end
@@ -41,14 +41,14 @@ shared_examples "relationable" do |relationable_model_name|
expect(page).to have_content(related1.title) expect(page).to have_content(related1.title)
end end
visit send("#{related1.class.name.downcase}_path", related1) visit related1.url
within("#related-content-list") do within("#related-content-list") do
expect(page).to have_content(relationable.title) expect(page).to have_content(relationable.title)
end end
within("#related_content") do within("#related_content") do
fill_in 'url', with: "#{Setting['url']}/#{related2.class.name.downcase.pluralize}/#{related2.to_param}" fill_in 'url', with: "#{Setting['url'] + related2.url}"
click_button "Add" click_button "Add"
end end
@@ -59,7 +59,7 @@ shared_examples "relationable" do |relationable_model_name|
scenario 'if related content URL is invalid returns error' do scenario 'if related content URL is invalid returns error' do
login_as(user) login_as(user)
visit send("#{relationable.class.name.downcase}_path", relationable) visit relationable.url
click_on("Add related content") click_on("Add related content")
@@ -75,7 +75,7 @@ shared_examples "relationable" do |relationable_model_name|
related_content = create(:related_content, parent_relationable: relationable, child_relationable: related1, author: build(:user)) related_content = create(:related_content, parent_relationable: relationable, child_relationable: related1, author: build(:user))
login_as(user) login_as(user)
visit send("#{relationable.class.name.downcase}_path", relationable) visit relationable.url
within("#related-content-list") do within("#related-content-list") do
find("#related-content-#{related_content.opposite_related_content.id}").hover find("#related-content-#{related_content.opposite_related_content.id}").hover
@@ -92,7 +92,7 @@ shared_examples "relationable" do |relationable_model_name|
related_content = create(:related_content, parent_relationable: relationable, child_relationable: related1, author: build(:user)) related_content = create(:related_content, parent_relationable: relationable, child_relationable: related1, author: build(:user))
login_as(user) login_as(user)
visit send("#{relationable.class.name.downcase}_path", relationable) visit relationable.url
within("#related-content-list") do within("#related-content-list") do
find("#related-content-#{related_content.opposite_related_content.id}").hover find("#related-content-#{related_content.opposite_related_content.id}").hover
@@ -117,7 +117,7 @@ shared_examples "relationable" do |relationable_model_name|
login_as(user) login_as(user)
visit send("#{relationable.class.name.downcase}_path", relationable) visit relationable.url
expect(page).not_to have_css("#related-content-list") expect(page).not_to have_css("#related-content-list")
end end