سؤال

I am using globalize3 with rails_admin thanks to this gist. What bugs me, is that the user can add as many translations as he wants.

Moreover, he isn't forced to translate the content in every single locale (as in I18n.available_locales). I'd like that. How can you tackle such a situation?

Models (shortened):

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
هل كانت مفيدة؟

المحلول

I ended up using Active Admin plus activeadmin-globalize3 instead. Much easier.

نصائح أخرى

It bugged me too, so I created custom field type that doesn't allow it.

The main class:

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

It inherits from RailsAdmin::Config::Fields::Association class, because it uses very similar to _form_nested_many partial (that's used in has_many type).

The partial:

.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)

It uses field.translations method from the custom field class, that returns an array of Translation objects. Every Translation object corresponds to available locale, and it's either an existing object from the database (if translation already exists) or new empty translation object.

E.g.

You've got this available locales:

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

You have Page model which includes some translated fields.

Also, you have an object of the class Page (a row in the database), that has translations for :en and :cz locales, but lacks one for the :ru.

So, field.translations method inside _form_globalize_tabs partial returns an array that contains: 2 existing translations for :en and :cz and 1 just initialized translation for :ru.

In the partial I'm passing this array to the fields_for helper method from nested_form gem, that returns 3 fieldsets for every translation object.

You can use this gem, if you don't want to mess with the code yourself: https://github.com/scarfaceDeb/rails_admin_globalize_field

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top