GithubHelp home page GithubHelp logo

i18n-active_record's Introduction

I18n::Backend::ActiveRecord Ruby Style Guide Tests Status Linter Status

This repository contains the I18n ActiveRecord backend and support code that has been extracted from the I18n gem: http://github.com/svenfuchs/i18n. It is fully compatible with Rails 4, 5 and 6.

Installation

For Bundler put the following in your Gemfile:

gem 'i18n-active_record', require: 'i18n/active_record'

After updating your bundle, run the installer

$ rails g i18n:active_record:install

It creates a migration:

class CreateTranslations < ActiveRecord::Migration
  def change
    create_table :translations do |t|
      t.string :locale
      t.string :key
      t.text :value
      t.text :interpolations
      t.boolean :is_proc, default: false

      t.timestamps
    end
  end
end

To specify table name use:

$ rails g i18n:active_record:install MyTranslation

With the translation model you will be able to manage your translation, and add new translations or languages through it.

By default the installer creates a new file in config/initializers named i18n_active_record.rb with the following content.

require 'i18n/backend/active_record'

Translation = I18n::Backend::ActiveRecord::Translation

if Translation.table_exists?
  I18n.backend = I18n::Backend::ActiveRecord.new

  I18n::Backend::ActiveRecord.send(:include, I18n::Backend::Memoize)
  I18n::Backend::Simple.send(:include, I18n::Backend::Memoize)
  I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)

  I18n.backend = I18n::Backend::Chain.new(I18n::Backend::Simple.new, I18n.backend)
end

To perform a simpler installation use:

$ rails g i18n:active_record:install --simple

It generates:

require 'i18n/backend/active_record'
I18n.backend = I18n::Backend::ActiveRecord.new

You may also configure whether the ActiveRecord backend should use destroy or delete when cleaning up internally.

I18n::Backend::ActiveRecord.configure do |config|
  config.cleanup_with_destroy = true # defaults to false
end

To configure the ActiveRecord backend to cache translations(might be useful in production) use:

I18n::Backend::ActiveRecord.configure do |config|
  config.cache_translations = true # defaults to false
end

Usage

You can now use I18n.t('Your String') to lookup translations in the database.

Custom translation model

By default, the gem relies on the built-in translation model.
However, to extend the default functionality, the translation model can be customized:

class MyTranslation < I18n::Backend::ActiveRecord::Translation
  def value=(val)
    super("custom #{val}")
  end
end

I18n::Backend::ActiveRecord.configure do |config|
  config.translation_model = MyTranslation
end

Missing Translations

To make the I18n::Backend::ActiveRecord::Missing module working correctly pluralization rules should be configured properly. The i18n.plural.keys translation key should be present in any of the backends. See https://github.com/svenfuchs/i18n-active_record/blob/master/lib/i18n/backend/active_record/missing.rb for more information.

en:
  i18n:
    plural:
      keys:
        - :zero
        - :one
        - :other

Interpolations

The interpolations field in the translations table is used by I18n::Backend::ActiveRecord::Missing to store the interpolations seen the first time this Translation was requested. This will help translators understand what interpolations to expect, and thus to include when providing the translations.

The interpolations field is otherwise unused since the "value" in Translation#value is actually used for interpolation during actual translations.

Examples

Contributing

Test suite

The test suite can be run with:

bundle exec rake

By default it runs the tests for SQLite database, to specify a database the DB env variable can be used:

DB=postgres bundle exec rake
DB=mysql bundle exec rake

To run tests for a specific rails version see Appraisal:

bundle exec appraisal rails-4 rake test

Maintainers

  • Sven Fuchs
  • Tim Masliuchenko

i18n-active_record's People

Contributors

23tux avatar abime avatar agustinf avatar avakhov avatar cbeer avatar dependabot[bot] avatar dorianmariecom avatar gingermusketeer avatar jeremyw avatar kaspth avatar mejackreed avatar mpataki avatar pawelnguyen avatar petergoldstein avatar plwalters avatar slbug avatar svenfuchs avatar timfjord avatar tomfast avatar vipera avatar westonganger avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

i18n-active_record's Issues

is_proc question

Hi,
thank you for your great gem. Could you help me in two dummies question?

  1. i don't understand what does it mean the is_proc field.... could you help me?

  2. how can i set a cache for this kind of i18n retrieving data from db?

lookup method not reusing @translations

Hi,

First of all, thanks for this great work, it's a very nice gem seems to cover a lot of cases nicely.

I am currently looking at performance issues and was wondering why the protected lookup method is not reusing @translations ? I imagine there is a balance between hitting the DB or parsing a huge in-memory hash, but that could reduce the DB workload in cases where tens or hundreds of translations are being pulled at the same time.

Would love to have your input on this!

Translations queries from database

While work with the gem I noticed that every translation key for current locale is taken from the database which generates about 100 DB queries in my case.

The suggestion is what about of getting all translations of current locale and then just take it from stored array or object? In this case it is only one query not 100.

If I`m missing something and such feature already present in such cool gem please let me know how to use it.
Thanks in advance!

Bug in Activerecord/YAML chained backend?

I have locales :en, :es, and :zh-TW. For each locale, I have a default YAML translation file. When I supply custom translations for all three locales, it works correctly. When I override ONLY the :en translation using ActiveRecord, the translations for the same key in :es and :zh-TW change to the custom :en translation instead of falling back to the YAML files (es.yml or zh-TW.yml).

Translations don't get updated quickly

Hello,

I'm using the gem and everything works good except that when I translate/update-translation something, it takes seconds and sometimes I need to reboot rails for the change to take effect. Is there a cache or something that makes that happen? May be related to unicorn?

Thanks

path for form helper

When making a form i got an error:

ActionView::Template::Error (undefined method 'i18n_backend_active_record_translation_path' for #<#<Class:0x00007f04a9399298>:0x00007f04917462c8>):
when adding url: translations_path to the form it worked again.
I think this originates from the initializer line:
Translation = I18n::Backend::ActiveRecord::Translation
There for Translation.name and Translation.sti_name is `I18n::Backend::ActiveRecord::Translation'

So when you call a form without an url parameter i18n_backend_active_record_translation_path is automatically generated for url.

Would be nice to ad a comment in the readme to put add "url: <translation_view_dir>_path" to form_with

old translations reappearing

Hi,

We use store_translations to store a new translation and then later use I18n.t to retrieve the translation. This works pretty well, but sometimes a previously stored translation will mysteriously re-appear on our web site after a few page refreshes. We've checked the database and it has the correct value. We've also cleared the browser cache, and and that doesn't help.

Has any one else seen this problem?

Thanks,
Ruby Duo

Added to attributes on the translation

Hi Sven Fuchs,

thank you very much for sharing!

I've forked the I18n-active_record gem and added ox_id and state to the translation in order to

  • publish only translation ready for 'production'
  • translate only keys belongs_to some superstructure (oxen in my scenario)

The ox_id will allow me to hold a number of translations specific to individual use cases, in one table like

  • use case #1 will translate citizen into 'bürger¨
  • use case #2 will translate citizen into "anwender"

all within the same Rails app (effectively providing me with means to run multiple customized use cases off one Rails app)

I'm not good at writing tests - and when I tried to rake testafter cloning - it failed utterly on me, which probably is my fault more than I18n-active_record - but anyway, just to emphasize that I have not been able to add any tests, should you want me to 'pull a request' :)

cheers,
Walther

Refactoring: renaming of column Translation#key because it's a reserved word for MySQL

The key column of Translation model should be renamend because key is a reserved word for MySQL or how do you get queries with key column as criteria working? I'm using MySQL 5.6.14.
See also http://dev.mysql.com/doc/refman/5.7/en/reserved-words.html

E.g. "SELECT DISTINCT(key) FROM translations;" throws:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key) FROM translations' at line 1

If the column can be renamed then I would volunteer for it to do the refactoring and make a pull request. Therefor I need to know the new name for the column? I cannot find a good name.

I18n is not missing constant RESERVED_KEYS!

i'm using i18n-active_record backend with rails master. in i18n initializer i have following code:

I18n::Backend::ActiveRecord.send(:include, I18n::Backend::Flatten)
I18n::Backend::ActiveRecord.send(:include, I18n::Backend::Memoize)
I18n::Backend::Simple.send(:include, I18n::Backend::Memoize)
I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
I18n::Backend::Chain.send(:include, I18n::Backend::ActiveRecord::Missing)

I18n.backend = I18n::Backend::Chain.new(I18n::Backend::Simple.new, I18n::Backend::ActiveRecord.new)

when some translation is missing it raises error "I18n is not missing constant RESERVED_KEYS!"

Full Trace:

/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/dependencies.rb:479:in `load_missing_constant'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/dependencies.rb:183:in `block in const_missing'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/dependencies.rb:181:in `each'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/dependencies.rb:181:in `const_missing'
/Users/user/.rvm/gems/ruby-head/bundler/gems/i18n-active_record-11c22d26a96f/lib/i18n/backend/active_record/missing.rb:44:in `store_default_translations'
/Users/user/.rvm/gems/ruby-head/bundler/gems/i18n-active_record-11c22d26a96f/lib/i18n/backend/active_record/missing.rb:59:in `rescue in translate'
/Users/user/.rvm/gems/ruby-head/bundler/gems/i18n-active_record-11c22d26a96f/lib/i18n/backend/active_record/missing.rb:57:in `translate'
i18n (0.5.0) lib/i18n.rb:155:in `translate'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_view/helpers/translation_helper.rb:48:in `translate'
app/views/sessions/new.html.haml:23:in `_app_views_sessions_new_html_haml___50053734192572560_2172121120'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_view/template.rb:139:in `block in render'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/notifications.rb:54:in `instrument'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_view/template.rb:137:in `render'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_view/renderer/template_renderer.rb:64:in `block (2 levels) in render_template'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_view/renderer/abstract_renderer.rb:34:in `block in instrument'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/notifications.rb:52:in `block in instrument'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/notifications.rb:52:in `instrument'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_view/renderer/abstract_renderer.rb:34:in `instrument'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_view/renderer/template_renderer.rb:63:in `block in render_template'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_view/renderer/template_renderer.rb:71:in `render_with_layout'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_view/renderer/template_renderer.rb:62:in `render_template'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_view/renderer/template_renderer.rb:18:in `block in render'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_view/renderer/abstract_renderer.rb:23:in `wrap_formats'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_view/renderer/template_renderer.rb:16:in `render'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_view/rendering.rb:99:in `_render_template'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_view/rendering.rb:27:in `render'
/Users/user/.rvm/gems/ruby-head/bundler/gems/haml-ec5fc0514f38/lib/haml/helpers/action_view_mods.rb:13:in `render_with_haml'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/abstract_controller/rendering.rb:114:in `_render_template'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/abstract_controller/rendering.rb:108:in `render_to_body'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_controller/metal/renderers.rb:29:in `render_to_body'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_controller/metal/compatibility.rb:46:in `render_to_body'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/abstract_controller/rendering.rb:101:in `render_to_string'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/abstract_controller/rendering.rb:92:in `render'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_controller/metal/rendering.rb:16:in `render'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_controller/metal/instrumentation.rb:40:in `block (2 levels) in render'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/core_ext/benchmark.rb:5:in `block in ms'
/Users/user/.rvm/rubies/ruby-head/lib/ruby/1.9.1/benchmark.rb:309:in `realtime'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/core_ext/benchmark.rb:5:in `ms'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_controller/metal/instrumentation.rb:40:in `block in render'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_controller/metal/instrumentation.rb:78:in `cleanup_view_runtime'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activerecord/lib/active_record/railties/controller_runtime.rb:15:in `cleanup_view_runtime'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_controller/metal/instrumentation.rb:39:in `render'
/Users/user/.rvm/gems/ruby-head/bundler/gems/devise-b50fd1a72e71/lib/devise/controllers/scoped_views.rb:28:in `render_with_scope'
/Users/user/.rvm/gems/ruby-head/bundler/gems/devise-b50fd1a72e71/app/controllers/devise/sessions_controller.rb:8:in `new'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_controller/metal/implicit_render.rb:4:in `send_action'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/abstract_controller/base.rb:151:in `process_action'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_controller/metal/rendering.rb:10:in `process_action'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/abstract_controller/callbacks.rb:18:in `block in process_action'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/callbacks.rb:450:in `_run__218572164128693654__process_action__159223568937014670__callbacks'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/callbacks.rb:404:in `_run_process_action_callbacks'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/callbacks.rb:93:in `run_callbacks'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/abstract_controller/callbacks.rb:17:in `process_action'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/notifications.rb:52:in `block in instrument'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/notifications.rb:52:in `instrument'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_controller/metal/instrumentation.rb:29:in `process_action'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_controller/metal/rescue.rb:17:in `process_action'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/abstract_controller/base.rb:120:in `process'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/abstract_controller/rendering.rb:39:in `process'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_controller/metal.rb:144:in `dispatch'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_controller/metal.rb:183:in `block in action'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_dispatch/routing/route_set.rb:62:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_dispatch/routing/route_set.rb:62:in `dispatch'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_dispatch/routing/route_set.rb:27:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_dispatch/routing/mapper.rb:36:in `call'
rack-mount (0.6.13) lib/rack/mount/route_set.rb:148:in `block in call'
rack-mount (0.6.13) lib/rack/mount/code_generation.rb:93:in `block in recognize'
rack-mount (0.6.13) lib/rack/mount/code_generation.rb:96:in `optimized_each'
rack-mount (0.6.13) lib/rack/mount/code_generation.rb:92:in `recognize'
rack-mount (0.6.13) lib/rack/mount/route_set.rb:139:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_dispatch/routing/route_set.rb:520:in `call'
oa-core (0.1.6) lib/omniauth/strategy.rb:50:in `call_app!'
oa-core (0.1.6) lib/omniauth/strategy.rb:32:in `call!'
oa-core (0.1.6) lib/omniauth/strategy.rb:19:in `call'
oa-core (0.1.6) lib/omniauth/strategy.rb:50:in `call_app!'
oa-core (0.1.6) lib/omniauth/strategy.rb:32:in `call!'
oa-core (0.1.6) lib/omniauth/strategy.rb:19:in `call'
oa-core (0.1.6) lib/omniauth/strategy.rb:50:in `call_app!'
oa-core (0.1.6) lib/omniauth/strategy.rb:32:in `call!'
oa-core (0.1.6) lib/omniauth/strategy.rb:19:in `call'
oa-core (0.1.6) lib/omniauth/strategy.rb:50:in `call_app!'
oa-core (0.1.6) lib/omniauth/strategy.rb:32:in `call!'
oa-core (0.1.6) lib/omniauth/strategy.rb:19:in `call'
oa-core (0.1.6) lib/omniauth/strategy.rb:50:in `call_app!'
oa-core (0.1.6) lib/omniauth/strategy.rb:32:in `call!'
oa-core (0.1.6) lib/omniauth/strategy.rb:19:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rack-recaptcha-ee41916e6530/lib/rack/recaptcha.rb:34:in `_call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rack-recaptcha-ee41916e6530/lib/rack/recaptcha.rb:24:in `call'
warden (1.0.2) lib/warden/manager.rb:35:in `block in call'
warden (1.0.2) lib/warden/manager.rb:34:in `catch'
warden (1.0.2) lib/warden/manager.rb:34:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rack-85ca454e6143/lib/rack/etag.rb:23:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rack-85ca454e6143/lib/rack/conditionalget.rb:25:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_dispatch/middleware/head.rb:14:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rack-85ca454e6143/lib/rack/methodoverride.rb:24:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_dispatch/middleware/params_parser.rb:21:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_dispatch/middleware/flash.rb:182:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rack-85ca454e6143/lib/rack/session/abstract/id.rb:192:in `context'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rack-85ca454e6143/lib/rack/session/abstract/id.rb:187:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_dispatch/middleware/cookies.rb:302:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activerecord/lib/active_record/query_cache.rb:32:in `block in call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:26:in `cache'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activerecord/lib/active_record/query_cache.rb:12:in `cache'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activerecord/lib/active_record/query_cache.rb:31:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:352:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_dispatch/middleware/callbacks.rb:48:in `block in call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/callbacks.rb:410:in `_run_call_callbacks'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_dispatch/middleware/callbacks.rb:46:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rack-85ca454e6143/lib/rack/sendfile.rb:102:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_dispatch/middleware/remote_ip.rb:48:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_dispatch/middleware/show_exceptions.rb:46:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/railties/lib/rails/rack/logger.rb:13:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rack-85ca454e6143/lib/rack/runtime.rb:17:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/activesupport/lib/active_support/cache/strategy/local_cache.rb:72:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rack-85ca454e6143/lib/rack/lock.rb:13:in `block in call'
:10:in `synchronize'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rack-85ca454e6143/lib/rack/lock.rb:13:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/actionpack/lib/action_dispatch/middleware/static.rb:60:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/railties/lib/rails/engine.rb:409:in `call'
/Users/user/.rvm/gems/ruby-head/bundler/gems/rails-896e25e994e2/railties/lib/rails/railtie/configurable.rb:30:in `method_missing'
passenger (3.0.0) lib/phusion_passenger/rack/request_handler.rb:96:in `process_request'
passenger (3.0.0) lib/phusion_passenger/abstract_request_handler.rb:513:in `accept_and_process_next_request'
passenger (3.0.0) lib/phusion_passenger/abstract_request_handler.rb:274:in `main_loop'
passenger (3.0.0) lib/phusion_passenger/rack/application_spawner.rb:205:in `start_request_handler'
passenger (3.0.0) lib/phusion_passenger/rack/application_spawner.rb:170:in `block in handle_spawn_application'
passenger (3.0.0) lib/phusion_passenger/utils.rb:479:in `safe_fork'
passenger (3.0.0) lib/phusion_passenger/rack/application_spawner.rb:165:in `handle_spawn_application'
passenger (3.0.0) lib/phusion_passenger/abstract_server.rb:357:in `server_main_loop'
passenger (3.0.0) lib/phusion_passenger/abstract_server.rb:206:in `start_synchronously'
passenger (3.0.0) lib/phusion_passenger/abstract_server.rb:180:in `start'
passenger (3.0.0) lib/phusion_passenger/rack/application_spawner.rb:128:in `start'
passenger (3.0.0) lib/phusion_passenger/spawn_manager.rb:253:in `block (2 levels) in spawn_rack_application'
passenger (3.0.0) lib/phusion_passenger/abstract_server_collection.rb:132:in `lookup_or_add'
passenger (3.0.0) lib/phusion_passenger/spawn_manager.rb:246:in `block in spawn_rack_application'
passenger (3.0.0) lib/phusion_passenger/abstract_server_collection.rb:82:in `block in synchronize'
:10:in `synchronize'
passenger (3.0.0) lib/phusion_passenger/abstract_server_collection.rb:79:in `synchronize'
passenger (3.0.0) lib/phusion_passenger/spawn_manager.rb:244:in `spawn_rack_application'
passenger (3.0.0) lib/phusion_passenger/spawn_manager.rb:137:in `spawn_application'
passenger (3.0.0) lib/phusion_passenger/spawn_manager.rb:275:in `handle_spawn_application'
passenger (3.0.0) lib/phusion_passenger/abstract_server.rb:357:in `server_main_loop'
passenger (3.0.0) lib/phusion_passenger/abstract_server.rb:206:in `start_synchronously'
passenger (3.0.0) helper-scripts/passenger-spawn-server:99:in `'

app/views/sessions/new.html.haml:23 containts "=t 'sign_in'"

config/initializers/i18n_active_record.rb not working

config/initializers/i18n_active_record.rb is configured like in the readme (auto generated)

translations from database are not loaded.

When placing:

require 'i18n/backend/active_record'
and
config.i18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n::Backend::Simple.new)

in config/application.rb translations from the db are loaded.

Serialize value field and accent

Hey svenfuchs,

got a problem with value which is serialize. In fact, when I import my yml files with store_translations, all my values where accents are present are transformed by unicode.

exemple :
"--- "Tentative de g\xC3\xA9olocalisation..."\n"

should be:
"--- "Tentative de géolocalisation..."\n"

is it a wrong yml file configuration or something else ?

thanks for your answer and see you at ruby lugdunum event ;)
Jerome

Hooks in Translation model don't work?

I tried setting up a before_save hook, but it's not triggering... Is there a way to make this model behave more like a real model? Because for now, I am also not using e.g. Translation.all, but I18n::Backend::ActiveRecord::Translation.all. It does NOT seem to be the same thing (returns different class types).
It would be nice to see some examples on proper usage as well.

Conflict with Rails 5 initializers order

Hi,

I have a newly created Rails 5.0.1 app which I added this gem to, and everything worked as expected.

However, a test began failing. The test was a unit test that checked whether a model's belongs_to association was working properly, and we are using the new Rails 5 "implicit" belongs_to validation.

Turns out that Rails 5.0.1 creates an initializer named new_framework_defaults.rb, and the README for this gem recommends creating an initializer named locale.rb. The thing is, locale.rb runs first, it does the set up, and only then new_framework_defaults.rb sets config.active_record.belongs_to_required_by_default = true.

I worked around it by creating an earlier initializer, active_record_belongs_to_required_by_default.rb, but this should probably be fixed in the gem itself.

There's a bunch of gems with this issue, and some of them have already merged PR's, see: rails/rails#23589.

Thanks for creating this gem! 👍

Present unique available locales

1.9.3p448 :001 > I18n.available_locales
I18n::Backend::ActiveRecord::Translation Load (117.4ms) SELECT DISTINCT "translations".* FROM "translations"
=> [:en]

1.9.3p448 :002 > I18n::Backend::ActiveRecord::Translation.available_locales
I18n::Backend::ActiveRecord::Translation Load (10.6ms) SELECT DISTINCT "translations".* FROM "translations"
=> [:en, :en, :en, :en, :en, :en, :en, :en, :en, :en, :en, :en, :en, :en, :en, :en, :en, :en, :en, :en,..]

locale.rb setting with advanced example issue?

Hi,

I Followed the installation guide, doing the simple setting in the locale.rb file, testing it with console and translations showed up properly on the frontend.

However, when I adopted the config example by Moritz, it was not working anymore and all the values fallback to the default ones in the YML files. Any idea why?

The Rails version is 5.1.4

User defined methods for I18n::Backend::ActiveRecord::Translation

Hi. I am trying to select the locale using a dropbox in a view.

This works fine:

<%= collection_select :selected_locale, :locale,
        Translation.select(:locale).distinct, :locale, :locale,
        {:selected => 'en'} %>

However, when trying to use a user-defined method for a friendlier locale name:

<%= collection_select :selected_locale, :locale,
        Translation.select(:locale).distinct, :locale, :friendly_locale_name,
        {:selected => 'English'} %>

I get the following error:

ActionView::Template::Error (undefined method 'friendly_locale_name' for #<I18n::Backend::ActiveRecord::Translation id: nil, locale: "es">):

I am defining friendly_locale_name in my Translation model which I guess is inheriting from I18n::Backend::ActiveRecord::Translation, so I don't understand why this fails.

class Translation < ActiveRecord::Base

  attr_accesor :friendly_locale_name

  def friendly_locale_name
    case self.locale
      when 'en'
          return 'English'
      when 'es'
        return 'Español'
      else
        return self.locale
    end
  end

end


Any help would be appreciated

i18n search yaml file first, then if not found refer to database

Using this gem i noticed that i18n search makes the app look in the database for a translation key first, then fall back to config/locales/*.yml files.

I have most of the translation values defined in yml file and few custom values are stored in database translation table, i have query result of 1000+ records contains multiple column values of various joined tables. so when using this gem to translate all the values, every translation key for current locale searches the database first and if not found refers to yaml files, which generates multiple DB queries which slow down the application performance.

The suggestion, reverse the current gem i18n search approach to look in the yaml file for a translation key first, then search in the database based on the lookup configuration option.

If this approach possible then multiple db queries can be avoided when the yaml file has major translations over database.

If this feature already present in the gem for any such configuration changes for the lookup; please let me know how to use it.
Thanks!

Rails app crashes when a null locale is present

Today I was investigating a startup failure in a Rails app with the following error:

/Users/sajoku/.rvm/gems/ruby-2.2.0/bundler/gems/i18n-active_record-2d9a22b6a4e5/lib/i18n/backend/active_record/translation.rb:76:in `block in available_locales': undefined method `to_sym' for nil:NilClass (NoMethodError)
        from /Users/sajoku/.rvm/gems/ruby-2.2.0/gems/activerecord-4.2.0/lib/active_record/relation/delegation.rb:46:in `map'

After some investigation the error led me (and my pair buddy) to the translations table in the database and check all the translations. The last two entries had NULL as :locale. Removing this fixed the startup issue.

I'm not sure if my "fix" is desirable but wanna check this out and let me know what you think?
sajoku@2f563cd
The reason I'm not sure is because this seems to be something the user could simply fix by making sure locale has a default value or can't be NULL in the database. What are your thought on this?

Or maybe let the user know in te README (or wiki perhaps?)?
sajoku@b284fee

Can't run tests

I'd like to contribute, but I can't figure out how to run the tests.

  • There's no top-level Gemfile
  • "rake test" produces:
test_helper.rb:1:in `require': no such file to load -- test_setup (LoadError)
  • If I fix that, then I get:
/Users/john/Development/i18n-active_record/ci/Gemfile.all not found
  • If I fix that, then I get:
/Users/john/.rvm/gems/ruby-1.8.7-p249/gems/rake-0.9.2.2/lib/rake/ext/module.rb:36:in `const_missing': uninitialized constant I18n::ActiveRecord::ConnectionNotEstablished (NameError)
    from /Users/john/Development/i18n-active_record/test/test_setup.rb:54:in `setup_active_record'

Time for a push to rubygems?

The last version that was pushed to rubygems was 0.0.2 in 2010: 0.0.2 - December 26, 2010

Perhaps it is time to push a new version? It seems like there have been several changes since then.

undefined method `map' for "translation missing: en-US.i18n.plural.keys":String

fairly standard rails 6 app.

stock standard i18n_active_record.rb initializer with the only addition being Missing

require 'i18n/backend/active_record'

Translation = I18n::Backend::ActiveRecord::Translation

if Translation.table_exists?
  I18n.backend = I18n::Backend::ActiveRecord.new

  I18n::Backend::ActiveRecord.include I18n::Backend::Memoize
  I18n::Backend::Simple.include I18n::Backend::Memoize
  I18n::Backend::Simple.include I18n::Backend::Pluralization

  I18n::Backend::Chain.send(:include, I18n::Backend::ActiveRecord::Missing)

  I18n.backend = I18n::Backend::Chain.new(I18n::Backend::Simple.new, I18n.backend)
end

I get the exception on line 45 of active_record/missing.rb

keys = count ? I18n.t('i18n.plural.keys', :locale => locale).map { |k| [key, k].join(FLATTEN_SEPARATOR) } : [key]

count is 1

a one line change to the failing line of count && count > 1 fixes my issue. I'm happy to do a PR for that but wanted to see if others are having a similar issue or if I have a config problem somewhere.

active_record/missing no longer functions

https://github.com/svenfuchs/i18n-active_record/blob/master/lib/i18n/backend/active_record/missing.rb#L57

It looks like I18n no longer raises the Exception MissingTranslationData, and instead throws an exception which is caught by I18n::ExceptionHandler which does not rethrow MissingTranslation and instead returns "translation missing: key_name".
https://github.com/svenfuchs/i18n/blob/master/lib/i18n/exceptions.rb#L13

Thus there is no error, and nothing to rescue, and thus this module does nothing.

I can hack the functions from Missing into a new ExceptionHandler and do what I want. But is there a better way?

Backend chain not working for complex keys?

Hi,

we have a problem using the i18n backend together with a standard yml file. We use a backend chain to use the yml file first (for performance), then the db backend. This works fine for most 'normal' keys, but fails in many Rails helper functions, for example number helpers. In those cases the gem looks up the key in the db.

This is our config:

db_backend = I18n::Backend::ActiveRecord.new
PERSISTED_I18N_BACKEND = db_backend

I18n::Backend::ActiveRecord.send(:include, I18n::Backend::Flatten)
I18n::Backend::Simple.send(:include, I18n::Backend::Memoize)
I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)

I18n.backend = I18n::Backend::Chain.new(I18n::Backend::Simple.new, db_backend)

Let's say we look up some word defined in en.yml:

> I18n.t :hello
 => "Hello"

But using a helper creates a db query, although the keys are defined in the yml file (the values from the file are also correctly used):

> include ActionView::Helpers::NumberHelper; number_to_currency(100)
  I18n::Backend::ActiveRecord::Translation Load (0.6ms)  SELECT `translations`.* FROM `translations` WHERE `translations`.`locale` = 'en' AND (`key` IN ('number.format') OR `key` LIKE 'number.format.%')
  I18n::Backend::ActiveRecord::Translation Load (0.4ms)  SELECT `translations`.* FROM `translations` WHERE `translations`.`locale` = 'en' AND (`key` IN ('number.currency.format') OR `key` LIKE 'number.currency.format.%')
  I18n::Backend::ActiveRecord::Translation Load (0.4ms)  SELECT `translations`.* FROM `translations` WHERE `translations`.`locale` = 'en' AND (`key` IN ('number.format') OR `key` LIKE 'number.format.%')
  I18n::Backend::ActiveRecord::Translation Load (0.3ms)  SELECT `translations`.* FROM `translations` WHERE `translations`.`locale` = 'en' AND (`key` IN ('number.precision.format') OR `key` LIKE 'number.precision.format.%')
  I18n::Backend::ActiveRecord::Translation Load (0.5ms)  SELECT `translations`.* FROM `translations` WHERE `translations`.`locale` = 'en' AND (`key` IN ('number.format') OR `key` LIKE 'number.format.%')
 => "100.00"

This also happens if I call such a key directly:

> I18n.t 'number.format'
  I18n::Backend::ActiveRecord::Translation Load (0.4ms)  SELECT `translations`.* FROM `translations` WHERE `translations`.`locale` = 'en' AND (`key` IN ('number.format') OR `key` LIKE 'number.format.%')
 => {:separator=>".", :delimiter=>",", :precision=>3, :significant=>false, :strip_insignificant_zeros=>false}

Any ideas?

Feature: :where option for t method that scopes translation

It would be very cool if you could add another column to the translations table like account_id or something and be able to scope translations down with something like I18n.t('welcome_message', where: {account_id: account_id}). It would broaden the use cases for this gem quite a bit as I have to implement this custom feature myself right now for our uses cases.

If you think it would be a good idea, I could work on a PR for it. I understand it doesn't conform to the higher level rails API, but there are advantages to querying your database directly over using YML. Why not leverage them?

Value at a parent node crashes the app

In my db I had the following two keys with a value:

"activerecord.models.resource.name"
"activerecord.models.resource.name.one"

This was my own fault and had nothing to do with this gem. But the result is that my Rails app crashed and that I got a undefined method 'split' for nil:NilClass error that took me too long to track down This was of course a case of GIGO but still it would be nice if this gem would not produce an obscure error message.

In my fork I implemented a simple solution that silently ignores the result of the parent and only returns the children. This makes for a more forgiving gem, which I would prefer. Disadvantage here is that you might end up with unreachable translations in your db as soon as you turn a child node into a parent node.

Another approach would be to raise a specific error revealing the cause of the problem.

I'll submit a PR with my fix, but if a different solution is preferred I can have a look at it as well.

serialize problems

i'm using i18n-active_record backend with rails master. in i18n initializer i have following code:

I18n::Backend::ActiveRecord.send(:include, I18n::Backend::Flatten)
I18n::Backend::ActiveRecord.send(:include, I18n::Backend::Memoize)
I18n::Backend::Simple.send(:include, I18n::Backend::Memoize)
I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
I18n::Backend::Chain.send(:include, I18n::Backend::ActiveRecord::Missing)

I18n.backend = I18n::Backend::Chain.new(I18n::Backend::Simple.new, I18n::Backend::ActiveRecord.new)

And because of 'serialize :value' in lib/i18n/backend/active_record/translation.rb AR serializes every field named value in any model, but everything ok using rails 3.0.3.
Seems like they changed something in include proccess and it includes 'serialize :value' and 'serialize :interpolations' to every model.
Can you please check it?

Fix StoreProc

Current implementation of the StoreProc doesn't support modern versions of ruby. This needs to be fixed

bundle failed

I'm trying to use this gem
gem 'i18n-active_record', :git => 'git://github.com/svenfuchs/i18n-active_record.git', :require => 'i18n/active_record'

and bundle failes to install it.

There was a LoadError while evaluating i18n-active_record.gemspec:
  cannot load such file -- i18n_active_record/version from
  /Users/user/.rvm/gems/ruby-head/bundler/gems/i18n-active_record-0482a489a1f6/i18n-active_record.gemspec:4:in `'

Does it try to require a relative path? That doesn't work in Ruby 1.9.

What happened to the rails-4-release branch?

I was using it for my rails 4 app, did it get merged into master and deleted? You should create a rails 4 release tag so we can have a reliable rails 4 version not subject to the working changes in master... The rubygems version is too old to use reliably. 0.1.0 was released in 2013!

PG::Error: ERROR: relation "translations" does not exist

Hello,

I have installed this gem on rails 4 and I kind of get into a loop.

If I run bundle install the gem gets installed, but when I try to run rake db:migrate I get the error from the title.

If I try to run rake db:migrate first, it says that my gem file is not up to date.

Is this a common problem or am I doing something wrong?

License missing from gemspec

RubyGems.org doesn't report a license for your gem. This is because it is not specified in the gemspec of your last release.

via e.g.

spec.license = 'MIT'
# or
spec.licenses = ['MIT', 'GPL-2']

Including a license in your gemspec is an easy way for rubygems.org and other tools to check how your gem is licensed. As you can imagine, scanning your repository for a LICENSE file or parsing the README, and then attempting to identify the license or licenses is much more difficult and more error prone. So, even for projects that already specify a license, including a license in your gemspec is a good practice. See, for example, how rubygems.org uses the gemspec to display the rails gem license.

There is even a License Finder gem to help companies/individuals ensure all gems they use meet their licensing needs. This tool depends on license information being available in the gemspec. This is an important enough issue that even Bundler now generates gems with a default 'MIT' license.

I hope you'll consider specifying a license in your gemspec. If not, please just close the issue with a nice message. In either case, I'll follow up. Thanks for your time!

Appendix:

If you need help choosing a license (sorry, I haven't checked your readme or looked for a license file), GitHub has created a license picker tool. Code without a license specified defaults to 'All rights reserved'-- denying others all rights to use of the code.
Here's a list of the license names I've found and their frequencies

p.s. In case you're wondering how I found you and why I made this issue, it's because I'm collecting stats on gems (I was originally looking for download data) and decided to collect license metadata,too, and make issues for gemspecs not specifying a license as a public service :). See the previous link or my blog post about this project for more information.

Rails4 compatible release

Hi Sven !
Master branch is used by OneSky for translations database backend, so I added this repo as a dependency for my project. Just let me know when/wether you plan to tag the current state, which seems rails 4 compatible.

Storing Procs

Just wanted to confirm, because parse_tree is not supported by ruby 1.9.x, the Store Procs feature will not work as well?

New translations appears in front only after restarting the server (Rails 5.1.3 / Gem Rails_Admin)

In my app, the BO is handle by Rails_Admin.

My translation model is displayed correctly and all the actions are working (create, edit, delete). I check in DB, and everything is updated.

The problem is, when i go see my page from the browser, even after a refresh, the old translation is still there. If i manually restart the server, the new one will be displayed.

I tried I18n.backend.reload!and Rails.cache.clearin my console but it doesn't fix anything.

Fetch translations subtree

Hi. I've stumbled upon such an issue. Lets say I have the following translation keys:

notifications.types.achievment_gained.message
notifications.types.content_created.message

If I want to fetch a subtree of my translations stored in database using notifications.types key it will return me a hash like this:

{:"achievement_gained.message"=>"achievement was gained",
 :"content_created.message"=>"content was created"}

But in order to correctly merge it with translations from other backends( I am using I18n::Backend::Chain) it should return hash like this

{:achievement_gained=>{:message=>"achievement was gained"},
 :content_created=>{:message=>"content was created"}}

Will you accept a PR with a fix for this?

How to make tests suite work

Hello,

I would love to help maintain and advance the test suite, but it the lastest change is from 3 years ago and with my limited (but growing!) knowledge of ruby I have been unable to make the test suite run :(

If anyone could help me get to an stable point where any of the present tests can be run, then I will try to update some and help maintain them.

How to use table of different name?

Hi, I need to move from YAML files to a database table for storing i18n data, but already have a model "Translation" in my app which is used otherwise. Is there any way to get i18n-active_record to use a different model and database table?

Using I18nAR in isolation

Hi guys, thanks for this amazing gem!

I was hoping to use this in an isolated portion of my site.

# initializers/i18n_active_record.rb
require 'i18n/backend/active_record'

I18nAR = I18n.clone
I18nAR.backend = I18n::Backend::ActiveRecord.new

The hope was with the above code I could do something like I18nAR.t("meow") in my views then it would explicitly use the database to pull the translation.

Problem is I was trying to duplicate the I18n singleton, but when I set the backend of the cloned, I18nAR it affects I18n and changes it to using this gem.

Any help would be much appreciated. Thanks!

struggling with mysql case sensitivity

i'm trying to use this backend to capture as-is english translations to support a GUI allowing translators to come in later and provide equivalent text for other languages. as a result, i need to have keys that are case sensitive so that "This Key" and "this key" are 2 separate keys...

i'm using mysql and case sensitive collation is just not available currently, but i can decorate the where clause searching for keys with the BINARY keyword -- and this works! -- but sadly, it's specific to mysql and i can't figure out a way to introduce it without the following nasty hack in lib/i18n/backend/active_record/translation.rb:

mysql_hack = 'BINARY ' if ::ActiveRecord::Base.connection.class.to_s =~ /mysql/i
scoped(:conditions => ["#{mysql_hack}#{column_name} IN (?) OR #{mysql_hack}#{column_name} LIKE ?", keys, namespace])

i would submit this as a pull request if i weren't so ashamed... :-)

if anyone has a better idea or even less smelly hack, please let me know...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.