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