Add budget investment translations

Also fix sort_by_title method [1]

[1] Use ruby sort instead of active record order scope because Globalize
does not provide a way to search over all available fallbacks when
translation for current locale does not exist.
This commit is contained in:
Senén Rodero Rodríguez
2018-12-23 00:25:23 +01:00
committed by voodoorai2000
parent 8c2f1b894d
commit eefb9ca4f7
4 changed files with 85 additions and 12 deletions

View File

@@ -28,6 +28,10 @@ class Budget
extend DownloadSettings::BudgetInvestmentCsv extend DownloadSettings::BudgetInvestmentCsv
translates :title, touch: true
translates :description, touch: true
include Globalizable
belongs_to :author, -> { with_hidden }, class_name: "User", foreign_key: "author_id" belongs_to :author, -> { with_hidden }, class_name: "User", foreign_key: "author_id"
belongs_to :heading belongs_to :heading
belongs_to :group belongs_to :group
@@ -48,15 +52,13 @@ class Budget
delegate :name, :email, to: :author, prefix: true delegate :name, :email, to: :author, prefix: true
validates :title, presence: true validates_translation :title, presence: true, length: { in: 4..Budget::Investment.title_max_length }
validates_translation :description, presence: true, length: { maximum: Budget::Investment.description_max_length }
validates :author, presence: true validates :author, presence: true
validates :description, presence: true
validates :heading_id, presence: true validates :heading_id, presence: true
validates :unfeasibility_explanation, presence: { if: :unfeasibility_explanation_required? } validates :unfeasibility_explanation, presence: { if: :unfeasibility_explanation_required? }
validates :price, presence: { if: :price_required? } validates :price, presence: { if: :price_required? }
validates :title, length: { in: 4..Budget::Investment.title_max_length }
validates :description, length: { maximum: Budget::Investment.description_max_length }
validates :terms_of_service, acceptance: { allow_nil: false }, on: :create validates :terms_of_service, acceptance: { allow_nil: false }, on: :create
scope :sort_by_confidence_score, -> { reorder(confidence_score: :desc, id: :desc) } scope :sort_by_confidence_score, -> { reorder(confidence_score: :desc, id: :desc) }
@@ -64,7 +66,6 @@ class Budget
scope :sort_by_price, -> { reorder(price: :desc, confidence_score: :desc, id: :desc) } scope :sort_by_price, -> { reorder(price: :desc, confidence_score: :desc, id: :desc) }
scope :sort_by_id, -> { order("id DESC") } scope :sort_by_id, -> { order("id DESC") }
scope :sort_by_title, -> { order("title ASC") }
scope :sort_by_supports, -> { order("cached_votes_up DESC") } scope :sort_by_supports, -> { order("cached_votes_up DESC") }
scope :valuation_open, -> { where(valuation_finished: false) } scope :valuation_open, -> { where(valuation_finished: false) }
@@ -117,6 +118,10 @@ class Budget
budget_investment_path(budget, self) budget_investment_path(budget, self)
end end
def self.sort_by_title
all.sort_by(&:title)
end
def self.filter_params(params) def self.filter_params(params)
params.permit(%i[heading_id group_id administrator_id tag_name valuator_id]) params.permit(%i[heading_id group_id administrator_id tag_name valuator_id])
end end
@@ -187,7 +192,7 @@ class Budget
if title_or_id =~ /^[0-9]+$/ if title_or_id =~ /^[0-9]+$/
results.where(id: title_or_id) results.where(id: title_or_id)
else else
results.where("title ILIKE ?", "%#{title_or_id}%") results.with_translations(I18n.locale).where("budget_investment_translations.title ILIKE ?", "%#{title_or_id}%")
end end
end end

View File

@@ -0,0 +1,15 @@
class AddBudgetInvestmentTranslations < ActiveRecord::Migration[4.2]
def self.up
Budget::Investment.create_translation_table!(
{
title: :string,
description: :text
},
{ migrate_data: true }
)
end
def self.down
Budget::Investment.drop_translation_table!
end
end

View File

@@ -234,6 +234,17 @@ ActiveRecord::Schema.define(version: 20190607160900) do
t.index ["hidden_at"], name: "index_budget_investment_statuses_on_hidden_at", using: :btree t.index ["hidden_at"], name: "index_budget_investment_statuses_on_hidden_at", using: :btree
end end
create_table "budget_investment_translations", force: :cascade do |t|
t.integer "budget_investment_id", null: false
t.string "locale", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "title"
t.text "description"
t.index ["budget_investment_id"], name: "index_budget_investment_translations_on_budget_investment_id", using: :btree
t.index ["locale"], name: "index_budget_investment_translations_on_locale", using: :btree
end
create_table "budget_investments", force: :cascade do |t| create_table "budget_investments", force: :cascade do |t|
t.integer "author_id" t.integer "author_id"
t.integer "administrator_id" t.integer "administrator_id"

View File

@@ -5,6 +5,8 @@ describe Budget::Investment do
describe "Concerns" do describe "Concerns" do
it_behaves_like "notifiable" it_behaves_like "notifiable"
it_behaves_like "globalizable", :budget_investment
it_behaves_like "acts as imageable", :budget_investment_image
end end
it "is valid" do it "is valid" do
@@ -33,14 +35,40 @@ describe Budget::Investment do
end end
end end
it_behaves_like "acts as imageable", "budget_investment_image" describe "#description" do
it "is sanitized" do
it "sanitizes description" do
investment.description = "<script>alert('danger');</script>" investment.description = "<script>alert('danger');</script>"
investment.valid? investment.valid?
expect(investment.description).to eq("alert('danger');") expect(investment.description).to eq("alert('danger');")
end end
it "is sanitized using globalize accessors" do
investment.description_en = "<script>alert('danger');</script>"
investment.valid?
expect(investment.description_en).to eq("alert('danger');")
end
it "is html_safe" do
investment.description = "<script>alert('danger');</script>"
investment.valid?
expect(investment.description).to be_html_safe
end
it "is html_safe using globalize accessors" do
investment.description_en = "<script>alert('danger');</script>"
investment.valid?
expect(investment.description_en).to be_html_safe
end
end
it "set correct group and budget ids" do it "set correct group and budget ids" do
budget = create(:budget) budget = create(:budget)
group_1 = create(:budget_group, budget: budget) group_1 = create(:budget_group, budget: budget)
@@ -549,6 +577,20 @@ describe Budget::Investment do
expect(described_class.unselected.sort).to eq [unselected_undecided_investment, unselected_feasible_investment].sort expect(described_class.unselected.sort).to eq [unselected_undecided_investment, unselected_feasible_investment].sort
end end
end end
describe "sort_by_title" do
it "should take into consideration title fallbacks when there is no
translation for current locale" do
english_investment = create(:budget_investment, :selected, title: "English title")
spanish_investment = Globalize.with_locale(:es) do
I18n.with_locale(:es) do
create(:budget_investment, :selected, title: "Título en español")
end
end
expect(described_class.sort_by_title).to eq [english_investment, spanish_investment]
end
end
end end
describe "apply_filters_and_search" do describe "apply_filters_and_search" do