diff --git a/app/assets/javascripts/map.js b/app/assets/javascripts/map.js
index 4b2e4a5a2..396ac5418 100644
--- a/app/assets/javascripts/map.js
+++ b/app/assets/javascripts/map.js
@@ -172,7 +172,7 @@
if (App.Map.validCoordinates(coordinates)) {
marker = createMarker(coordinates.lat, coordinates.long);
marker.options.id = coordinates.investment_id;
- marker.on("click", App.Map.openMarkerPopup);
+ marker.bindPopup(App.Map.getPopupContent(coordinates));
}
});
}
@@ -217,19 +217,8 @@
polygon.addTo(map);
},
- openMarkerPopup: function(e) {
- var marker = e.target;
- $.ajax("/investments/" + marker.options.id + "/json_data", {
- type: "GET",
- dataType: "json",
- success: function(data) {
- e.target.bindPopup(App.Map.getPopupContent(data)).openPopup();
- }
- });
- },
getPopupContent: function(data) {
- return "" +
- data.investment_title + "";
+ return "" + data.title + "";
},
validZoom: function(zoom) {
return App.Map.isNumeric(zoom);
diff --git a/app/components/budgets/investments/map_component.rb b/app/components/budgets/investments/map_component.rb
index 897524ca2..43253dfed 100644
--- a/app/components/budgets/investments/map_component.rb
+++ b/app/components/budgets/investments/map_component.rb
@@ -18,7 +18,7 @@ class Budgets::Investments::MapComponent < ApplicationComponent
end
def coordinates
- MapLocation.where(investment: investments).map(&:json_data)
+ MapLocation.investments_json_data(investments.unscope(:order))
end
def geozones_data
diff --git a/app/components/budgets/map_component.rb b/app/components/budgets/map_component.rb
index dcbc427d6..ccf3719d1 100644
--- a/app/components/budgets/map_component.rb
+++ b/app/components/budgets/map_component.rb
@@ -19,7 +19,7 @@ class Budgets::MapComponent < ApplicationComponent
investments = budget.investments
end
- MapLocation.where(investment_id: investments).map(&:json_data)
+ MapLocation.investments_json_data(investments)
end
def geozones_data
diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb
index 84277042f..c192827c4 100644
--- a/app/controllers/budgets/investments_controller.rb
+++ b/app/controllers/budgets/investments_controller.rb
@@ -11,12 +11,11 @@ module Budgets
PER_PAGE = 10
- before_action :authenticate_user!, except: [:index, :show, :json_data]
- before_action :load_budget, except: :json_data
+ before_action :authenticate_user!, except: [:index, :show]
+ before_action :load_budget
- authorize_resource :budget, except: :json_data
- load_and_authorize_resource :investment, through: :budget, class: "Budget::Investment",
- except: :json_data
+ authorize_resource :budget
+ load_and_authorize_resource :investment, through: :budget, class: "Budget::Investment"
before_action :load_ballot, only: [:index, :show]
before_action :load_heading, only: [:index, :show]
@@ -25,8 +24,6 @@ module Budgets
before_action :set_default_investment_filter, only: :index
before_action :set_view, only: :index
- skip_authorization_check only: :json_data
-
feature_flag :budgets
has_orders %w[most_voted newest oldest], only: :show
@@ -91,19 +88,6 @@ module Budgets
super
end
- def json_data
- investment = Budget::Investment.find(params[:id])
- data = {
- investment_id: investment.id,
- investment_title: investment.title,
- budget_id: investment.budget.id
- }.to_json
-
- respond_to do |format|
- format.json { render json: data }
- end
- end
-
private
def resource_model
diff --git a/app/models/abilities/everyone.rb b/app/models/abilities/everyone.rb
index 7052c48d5..252ce3896 100644
--- a/app/models/abilities/everyone.rb
+++ b/app/models/abilities/everyone.rb
@@ -14,7 +14,7 @@ module Abilities
can [:read, :welcome], Budget
can [:read], Budget
can [:read], Budget::Group
- can [:read, :print, :json_data], Budget::Investment
+ can [:read, :print], Budget::Investment
can :read_results, Budget, id: Budget.finished.results_enabled.ids
can :read_stats, Budget, id: Budget.valuating_or_later.stats_enabled.ids
can :read_executions, Budget, phase: "finished"
diff --git a/app/models/concerns/globalizable.rb b/app/models/concerns/globalizable.rb
index c2e04554f..0b995350d 100644
--- a/app/models/concerns/globalizable.rb
+++ b/app/models/concerns/globalizable.rb
@@ -100,5 +100,22 @@ module Globalizable
def translation_class_delegate(method)
translation_class.instance_eval { delegate method, to: :globalized_model }
end
+
+ def with_fallback_translation
+ translations_foreign_key = reflect_on_association(:translations).foreign_key
+ fallbacks = Globalize.fallbacks(Globalize.locale)
+
+ fallbacks_with_order = fallbacks.map.with_index do |locale, order|
+ "('#{locale}', #{order})"
+ end.join(", ")
+
+ translations_ids = translation_class
+ .select("DISTINCT ON (#{translations_foreign_key}) id")
+ .where(locale: fallbacks)
+ .joins("LEFT JOIN (VALUES #{fallbacks_with_order}) AS locales(name, ordering) ON locale = locales.name")
+ .order(translations_foreign_key, "locales.ordering")
+
+ with_translations(fallbacks).where("#{translations_table_name}.id": translations_ids)
+ end
end
end
diff --git a/app/models/map_location.rb b/app/models/map_location.rb
index 6ed4fc9cc..7adc6d639 100644
--- a/app/models/map_location.rb
+++ b/app/models/map_location.rb
@@ -24,4 +24,23 @@ class MapLocation < ApplicationRecord
longitude: (heading.longitude.to_f if heading.longitude.present?)
)
end
+
+ def self.investments_json_data(investments)
+ return [] unless investments.any?
+
+ budget_id = investments.first.budget_id
+
+ data = investments.joins(:map_location)
+ .with_fallback_translation
+ .pluck(:id, :title, :latitude, :longitude)
+
+ data.map do |values|
+ {
+ title: values[1],
+ link: "/budgets/#{budget_id}/investments/#{values[0]}",
+ lat: values[2],
+ long: values[3]
+ }
+ end
+ end
end
diff --git a/config/routes/budget.rb b/config/routes/budget.rb
index 6d173af87..f6054d95f 100644
--- a/config/routes/budget.rb
+++ b/config/routes/budget.rb
@@ -23,6 +23,3 @@ end
resolve "Budget::Investment" do |investment, options|
[investment.budget, :investment, options.merge(id: investment)]
end
-
-get "investments/:id/json_data", action: :json_data, controller: "budgets/investments"
-get "/budgets/:budget_id/investments/:id/json_data", action: :json_data, controller: "budgets/investments"
diff --git a/spec/models/concerns/globalizable.rb b/spec/models/concerns/globalizable.rb
index 0eca3b268..fd74d09c1 100644
--- a/spec/models/concerns/globalizable.rb
+++ b/spec/models/concerns/globalizable.rb
@@ -15,10 +15,7 @@ shared_examples_for "globalizable" do |factory_name|
before do
record.update!(attribute => "In English")
- I18n.with_locale(:es) do
- record.update!(required_fields.index_with("En español"))
- record.update!(attribute => "En español")
- end
+ add_translation(record, :es, "En español")
record.reload
end
@@ -98,7 +95,7 @@ shared_examples_for "globalizable" do |factory_name|
end
it "Does not automatically add a translation for the current locale" do
- record.translations.find_by(locale: :en).destroy!
+ destroy_translation(record, :en)
record.reload
record.update!(translations_attributes: [
@@ -188,4 +185,62 @@ shared_examples_for "globalizable" do |factory_name|
expect(record.send(attribute)).to eq "Deutsche Sprache"
end
end
+
+ describe ".with_fallback_translation" do
+ before do
+ fallbacks = { fr: %i[fr en es], es: %i[es fr en], en: %i[en es fr] }
+ allow(I18n).to receive(:fallbacks).and_return(I18n.fallbacks.merge(fallbacks))
+ Globalize.set_fallbacks_to_all_available_locales
+ end
+
+ it "returns records with the best fallback translation available for the current locale" do
+ record.update!(attribute => "Content in English")
+ add_translation(record, :es, "Contenido en español")
+ add_translation(record, :fr, "Contenu en français")
+
+ I18n.with_locale(:es) do
+ expect(attribute_with_fallback_translation(record, attribute)).to eq "Contenido en español"
+
+ destroy_translation(record, :es)
+
+ expect(attribute_with_fallback_translation(record, attribute)).to eq "Contenu en français"
+
+ destroy_translation(record, :fr)
+
+ expect(attribute_with_fallback_translation(record, attribute)).to eq "Content in English"
+ end
+
+ record.reload
+
+ add_translation(record, :es, "Contenido en español")
+ add_translation(record, :fr, "Contenu en français")
+
+ I18n.with_locale(:fr) do
+ expect(attribute_with_fallback_translation(record, attribute)).to eq "Contenu en français"
+
+ destroy_translation(record, :fr)
+
+ expect(attribute_with_fallback_translation(record, attribute)).to eq "Content in English"
+
+ destroy_translation(record, :en)
+
+ expect(attribute_with_fallback_translation(record, attribute)).to eq "Contenido en español"
+ end
+ end
+ end
+end
+
+def add_translation(record, locale, text)
+ I18n.with_locale(locale) do
+ record.update!(required_fields.index_with(text))
+ record.update!(attribute => text)
+ end
+end
+
+def destroy_translation(record, locale)
+ record.translations.find_by(locale: locale).destroy!
+end
+
+def attribute_with_fallback_translation(record, attribute)
+ record.class.with_fallback_translation.where(id: record.id).pick(attribute)
end