ruby-on-railscsvmobility

Importing via csv data in jsonb format


Using the mobility gem for i18n, the process of importing data from CSV for jsonb data is not succeeding.

Whereas, one generally imports

Class.create(
  name_en: row[2],
  name_fr: row[3],
  [...]

for the local-driven values in a key_value backend, with a postgresql backend the column has to be populated with hash, with the key and value.

However, the syntax is incorrect name: { 'en' = row[2], 'fr' = row[2]} leads to error
syntax error, unexpected '=', expecting '.' or &. or :: or '['

and name: { 'en': row[2], 'fr': row[2]} seems syntaxtically correct, but yields
Error importing row because 'No plugin configured for these keys: type.'

note this occurs with any of the following definitions in config/initializers/mobility.rb`

    backend :jsonb
    backend :jsonb, type: :json
    backend :jsonb, type: :string

Solution

  • Managed to set it up. It's actually straightforward, mobility's docs on github make it more confusing than it is.

    Set up your migrations with jsonb columns for each attribute, it's recommended to set default as well default: {}.

    # db/migrate/20220402201700_create_articles.rb
    class CreateArticles < ActiveRecord::Migration[7.0]
      def change
        create_table :articles do |t|
          t.jsonb :title, default: {}
        end
      end
    end
    

    Model set up is unchanged https://github.com/shioyama/mobility#getting-started

    # app/models/article.rb
    class Article < ApplicationRecord
      extend Mobility
      translates :title
    end
    

    To set up locale accessors, locale_accessors plugin must be enabled. https://github.com/shioyama/mobility#-getting-and-setting-translations

    # config/initializers/mobility.rb
    Mobility.configure do
      plugins do
        backend :jsonb
        locale_accessors # enable locale accessors, like 'name_en'
        # ...
      end
    end
    

    Import transaltions

    Article.create(title_en: 'Importing via csv data in jsonb format',
                   title_fr: 'Importation via des données csv au format jsonb')
    
    # Article.last.title_backend.read(:fr) # => "Importation via des ..."
    
    # this doesn't work, as far as I can tell
    # it'll wrap the entire hash in `en` locale
    Article.create(title: { en: '', fr: ''} )
    

    For other ways to save translations: https://github.com/shioyama/mobility#-getting-and-setting-translations

    mobility v1.2.6 rails v7.0.2.3 ruby v3.1.1