Рельсы заставляют все переводы

Я использую globalize3 с rails_admin благодаря этой сути. Что меня беспокоит, так это то, что пользователь может добавить столько переводов, сколько захочет.

Более того, он не обязан переводить контент в каждой локали (как в I18n.available_locales). Я хотел бы, что. Как вы можете справиться с такой ситуацией?

Модели (сокращенно):

class Project < ActiveRecord::Base
    has_many :project_translations, :dependent => :destroy, :inverse_of => :project
    accepts_nested_attributes_for :project_translations, :allow_destroy => true

class ProjectTranslation < ActiveRecord::Base
    belongs_to :project

2 ответа

Решение

В итоге я выбрал Active Admin плюс activeadmin-globalize3. Намного легче.

Это тоже меня раздражало, поэтому я создал собственный тип поля, который не позволяет этого.

Основной класс:

module RailsAdmin
  module Config
    module Fields
      module Types
        class GlobalizeTabs < RailsAdmin::Config::Fields::Association
          RailsAdmin::Config::Fields::Types::register(:globalize_tabs, self)

          register_instance_option :partial do
            :form_globalize_tabs
          end

          def method_name
            "#{super}_attributes".to_sym
          end

          # Reader for validation errors of the bound object
          def errors
            bindings[:object].errors[name]
          end

          def available_locales
            I18n.available_locales
          end
          def current_locale
            I18n.locale
          end

          # Returns array of Translation objects
          # It gets existing or creates new empty translation for every locale
          # It's used in fields_for method in partial
          def translations
            translated_locales = @bindings[:object].translated_locales
            available_locales.collect do |locale|
              translated_locales.include?(locale) ? @bindings[:object].translation_for(locale) : @bindings[:object].translations.new({ locale: locale })
            end
          end
        end
      end
    end
  end
end

Наследуется от RailsAdmin::Config::Fields::Association класс, потому что он использует очень похоже на _form_nested_many частичное (используется в типе has_many).

Частичное:

.controls
  = form.errors_for(field)
  %ul.nav.nav-tabs{ :style => 'margin-top:5px' }
    - field.available_locales.each do |locale|
      %li{ class: ( 'active' if locale == field.current_locale ) }
        %a{ href: "##{locale}", data: { toggle: "tab" } }= locale
.tab-content
  = form.fields_for field.name, field.translations, wrapper: false do |nested_form|
    .fields.tab-pane{ id: nested_form.object.locale, class: ( 'active' if nested_form.object.locale == field.current_locale ) }
      = nested_form.generate({:action => :nested, :model_config => field.associated_model_config, :nested_in => field.name })
= form.help_for(field)

Оно использует field.translations метод из класса пользовательских полей, который возвращает массив объектов Translation. Каждый объект перевода соответствует доступной локали, и это либо существующий объект из базы данных (если перевод уже существует), либо новый пустой объект перевода.

Например

У вас есть доступные локали:

I18n.available_locales = [:en, :cz, :ru]

У вас есть модель страницы, которая включает некоторые переведенные поля.

Кроме того, у вас есть объект класса Page (строка в базе данных), у которого есть переводы для: en и: cz locales, но отсутствует объект для: ru.

Так, field.translations метод внутри _form_globalize_tabs частичное возвращает массив, который содержит: 2 существующих перевода для: en и: cz и 1 только что инициализированный перевод для: ru.

В частичном я передаю этот массив в fields_for вспомогательный метод из nested_form gem, который возвращает 3 набора полей для каждого объекта перевода.

Вы можете использовать этот драгоценный камень, если вы не хотите возиться с кодом самостоятельно: https://github.com/scarfaceDeb/rails_admin_globalize_field

Другие вопросы по тегам