Skip to content

Commit

Permalink
Set proxy getter and setters for localized translations
Browse files Browse the repository at this point in the history
  • Loading branch information
virolea committed Sep 30, 2024
1 parent 1c76451 commit dc0efb0
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 22 deletions.
16 changes: 3 additions & 13 deletions app/controllers/rosetta/translations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,12 @@ class TranslationsController < ApplicationController
include LocaleScoped

before_action :set_translation_key
before_action :set_translation

def edit
end

def update
if translation_params[:value].blank?
@translation_key.public_send(:"#{@locale.code}_translation=", nil)
else
@translation.update(translation_params)
end
@translation_key.update(translation_key_params)

render partial: "rosetta/locales/translations/translation_key", locals: { translation_key: @translation_key }
end
Expand All @@ -24,13 +19,8 @@ def set_translation_key
@translation_key = TranslationKey.find(params[:translation_key_id])
end

def set_translation
@translation = @translation_key.public_send(:"#{@locale.code}_translation") ||
@translation_key.public_send(:"build_#{@locale.code}_translation")
end

def translation_params
params.require(:translation).permit(:value)
def translation_key_params
params.require(:translation_key).permit(:"value_#{@locale.code}")
end
end
end
6 changes: 3 additions & 3 deletions app/views/rosetta/translations/edit.html.erb
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<%= turbo_frame_tag dom_id(@translation_key) do %>
<%= form_with model: @translation, url: translation_key_translation_path(@translation_key), method: :patch, class: "relative" do |f| %>
<%= form_with model: @translation_key, url: translation_key_translation_path(@translation_key), method: :patch, class: "relative" do |f| %>
<%= hidden_field_tag :locale_id, @locale.id %>

<div class="overflow-hidden rounded-lg shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-indigo-600">
<%= f.label :value, "Translation", class: "sr-only" %>
<%= f.text_area :value, row: 3, autofocus: true, placeholder: "Enter your translation", class: "block w-full resize-none border-0 bg-transparent py-1.5 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6" %>
<%= f.label :"value_#{@locale.code}", "Translation", class: "sr-only" %>
<%= f.text_area :"value_#{@locale.code}", row: 3, autofocus: true, placeholder: "Enter your translation", class: "block w-full resize-none border-0 bg-transparent py-1.5 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6" %>

<div class="py-2" aria-hidden="true">
<div class="py-px">
Expand Down
2 changes: 2 additions & 0 deletions lib/rosetta-rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
require "rosetta/configuration"

require "rosetta/translated"
require "rosetta/translated/create"
require "rosetta/translated/delete"

module Rosetta
module Base
Expand Down
26 changes: 24 additions & 2 deletions lib/rosetta/translated.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,33 @@ def translated_in(locale)

scope :with_translation, ->(locale) { includes(:"#{locale.code}_translation") }
scope :with_missing_translation, ->(locale) { with_translation(locale).where.missing(:"#{locale.code}_translation") }

define_method("value_#{locale.code}") do
if translation_changes[locale.code]
translation_changes[locale.code].value
else
public_send(:"#{locale.code}_translation")&.value
end
end

define_method("value_#{locale.code}=") do |locale_value|
translation_changes[locale.code] = if locale_value.blank?
Rosetta::Translated::Delete.new(self, locale)
else
Rosetta::Translated::Create.new(self, locale, locale_value)
end
end

after_save { translation_changes[locale.code]&.save }
end
end

def translation_in(locale)
public_send(:"#{locale.code}_translation")
def translation_changes
@translation_changes ||= {}
end

def reload(*)
super.tap { @translation_changes = nil }
end
end
end
20 changes: 20 additions & 0 deletions lib/rosetta/translated/create.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module Rosetta
class Translated::Create
attr_reader :value

def initialize(record, locale, value)
@record = record
@locale = locale
@value = value
end

def save
translation.value = @value
@record.public_send(:"#{@locale.code}_translation=", translation)
end

def translation
@translation ||= @record.public_send(:"build_#{@locale.code}_translation")
end
end
end
15 changes: 15 additions & 0 deletions lib/rosetta/translated/delete.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Rosetta
class Translated::Delete
attr_reader :value

def initialize(record, locale)
@record = record
@locale = locale
@value = nil
end

def save
@record.public_send(:"#{@locale.code}_translation=", nil)
end
end
end
6 changes: 3 additions & 3 deletions test/controllers/rosetta/translations_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class TranslationsControllerTest < ActionDispatch::IntegrationTest

test "add a new translation" do
assert_difference("Translation.count", 1) do
patch translation_key_translation_path(@key), params: { locale_id: @locale.id, translation: { value: "Au revoir" } }
patch translation_key_translation_path(@key), params: { locale_id: @locale.id, translation_key: { value_fr: "Au revoir" } }
end

assert_equal "Au revoir", Translation.last.value
Expand All @@ -28,7 +28,7 @@ class TranslationsControllerTest < ActionDispatch::IntegrationTest
Translation.create!(locale: @locale, translation_key: @key, value: "Salut")

assert_no_difference("Translation.count") do
patch translation_key_translation_path(@key), params: { locale_id: @locale.id, translation: { value: "Bonjour" } }
patch translation_key_translation_path(@key), params: { locale_id: @locale.id, translation_key: { value_fr: "Bonjour" } }
end

assert_equal "Bonjour", Translation.last.value
Expand All @@ -40,7 +40,7 @@ class TranslationsControllerTest < ActionDispatch::IntegrationTest
Translation.create!(locale: @locale, translation_key: @key, value: "Salut")

assert_difference("Translation.count", -1) do
patch translation_key_translation_path(@key), params: { locale_id: @locale.id, translation: { value: "" } }
patch translation_key_translation_path(@key), params: { locale_id: @locale.id, translation_key: { value_fr: "" } }
end

assert_response :success
Expand Down
2 changes: 1 addition & 1 deletion test/integration/translations_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class TranslationsTest < ActionDispatch::IntegrationTest
key = Rosetta::TranslationKey.create(value: "Available locales")

# Create the translation
patch rosetta.translation_key_translation_path(key), params: { locale_id: locale.id, translation: { value: "Langues disponibles" } }
patch rosetta.translation_key_translation_path(key), params: { locale_id: locale.id, translation_key: { value_fr: "Langues disponibles" } }

# Deploy the changes
post rosetta.locale_deploys_path(locale)
Expand Down
32 changes: 32 additions & 0 deletions test/lib/rosetta/translated_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require "test_helper"

class Rosetta::TranslatedTest < ActiveSupport::TestCase
include ActiveJob::TestHelper

test "setting a new translation" do
translation_key = rosetta_translation_keys(:goodbye)
translation_key.update(value_fr: "au revoir")
translation_key.reload

assert_equal "au revoir", translation_key.value_fr
assert_not_nil translation_key.fr_translation
end

test "setting a translation to blank removes the translation" do
translation_key = rosetta_translation_keys(:hello)

translation_key.update(value_fr: "")
translation_key.reload

assert_nil translation_key.value_fr
assert_nil translation_key.fr_translation
end

test "setting a translation without saving returns the updated translation" do
translation_key = rosetta_translation_keys(:hello)
translation_key.value_fr = "salut"

assert_equal "salut", translation_key.value_fr
assert_equal "bonjour", translation_key.reload.value_fr
end
end

0 comments on commit dc0efb0

Please sign in to comment.