GithubHelp home page GithubHelp logo

globalize2's Introduction

Globalize2

Globalize2 is the successor of Globalize for Rails.

It is compatible with and builds on the new I18n api in Ruby on Rails. and adds model translations to ActiveRecord.

Globalize2 is much more lightweight and compatible than its predecessor was. Model translations in Globalize2 use default ActiveRecord features and do not limit any ActiveRecord functionality any more.

Requirements

ActiveRecord
I18n

(or Rails > 2.2)

Installation

To install Globalize2 with its default setup just use:


script/plugin install git://github.com/joshmh/globalize2.git

Model translations

Model translations allow you to translate your models’ attribute values. E.g.


class Post < ActiveRecord::Base
  translates :title, :text
end

Allows you to values for the attributes :title and :text per locale:


I18n.locale = :en
post.title # => Globalize2 rocks!

I18n.locale = :he
post.title # => גלובאלייז2 שולט!

In order to make this work, you’ll need to add the appropriate translation tables. Globalize2 comes with a handy helper method to help you do this. It’s called create_translation_table!. Here’s an example:


class CreatePosts < ActiveRecord::Migration
  def self.up
    create_table :posts do |t|
      t.timestamps
    end
    Post.create_translation_table! :title => :string, :text => :text
  end
  def self.down
    drop_table :posts
    Post.drop_translation_table!
  end
end

Note that the ActiveRecord model Post must already exist and have a translates directive listing the translated fields.

Migration from Globalize

See this script by Tomasz Stachewicz: http://gist.github.com/120867

Changes since Globalize2 v0.1.0

  • The association globalize_translations has been renamed to translations.

Alternative Solutions

  • Veger’s fork – uses default AR schema for the default locale, delegates to the translations table for other locales only
  • TranslatableColumns – have multiple languages of the same attribute in a model (Iain Hecker)
  • localized_record – allows records to have localized attributes without any modifications to the database (Glenn Powell)
  • model_translations – Minimal implementation of Globalize2 style model translations (Jan Andersson)

Related solutions

globalize2's People

Contributors

hukl avatar joshmh avatar mseppae avatar phuesler avatar zencocoon 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

globalize2's Issues

Breaks irregular pluralizations

I'm using Rails 2.3.3 and have an irregular pluralization for curriculum and globalize2 is inadvertantly messing up the pluralization. In this example, I have a model named "TranslatedCurriculum" with table named "translated_curricula" and a model named "UntranslatedCurriculum" with a table named "untranslated_curricula". The TranslatedCurriculum has model translations, the UntranslatedCurriculum does not. If I boot up a console, I'll get the following:
>> TranslatedCurriculum.table_name
=> "translated_curriculums"
>> UntranslatedCurriculum.table_name
=> "untranslated_curricula"

Notice that the TranslatedCurriculum is wrong (this leads to no queries working...). The reason for this problem is that the translates() method in globalize2 is causing 'table_name' to be called on the TranslatedCurriculum object, thereby causing the table_name to be set for all time, since base.rb eventually calls set_table_name, which is defined as
def set_table_name(value = nil, &block)
define_attr_method :table_name, value, &block
end
Since the irregular inflections haven't been loaded at this point, the incorrect inflection is saved.

I was able to fix this by patching the translates() method to have the following at the bottom of the method:
define_attr_method :table_name do
reset_table_name
end
which will mean that the table_name will be set at a later point in time (hopefully when the inflections have been loaded).

If you're trying to reproduce this, my environment.rb had the following block:
ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 'curriculum', 'curricula'
end

Using create_translation_table on a working application

Would be nice to have something to get better migrations when you already have some elements of a model you want to add globalize2 support.

The table is created, but the current entries won't show anything on the translated fields. Also, the original field isn't destroyed, which might create problems.

What we do is iterate through the current elements creating entries on all the locales, and then destroy the original attribute.

table prefix

create_translation_table! doesn't work correctly when I set a table prefix in my environment.rb:
config.active_record.table_name_prefix= '_'

here's my solution:
in file lib/globalize/model/active_record.rb
change

self.connection.create_table(translation_table_name) do |t|

with

self.connection.create_table("#{table_name_prefix}#{translation_table_name}#{table_name_suffix}") do |t|

bye

Devis_

model.clone() not working as exprected on translated columns

On Rails 2.3.4, given I have a record_title-model:

% script/console test

r = RecordTitle.first RecordTitle id: 10000, infotype: "SI", docno: "0258", unitno: "38", text: "Vel voluptate aliquid et doloribus sint eum ad sequ...", fun_group_id: 10000, fun_subgroup_id: 10000, created_at: "2001-11-14 23:00:00", updated_at: "2008-05-23 22:00:00", state: "draft" rc = r.clone RecordTitle id: nil, infotype: "SI", docno: "0258", unitno: "38", text: "Vel voluptate aliquid et doloribus sint eum ad sequ...", fun_group_id: 10000, fun_subgroup_id: 10000, created_at: "2001-11-14 23:00:00", updated_at: "2008-05-23 22:00:00", state: "draft" rc.text nil r.text "Vel voluptate aliquid et doloribus sint eum ad sequi."

Even after saving the newly cloned model, the text remains empty. Thus it is not cloned as all the other atributes.

Chained Backend doesn't provide reload! method

Chained backend cannot be used in development environment in Rails 2.3.4

config.cache_classes = false

I18n.backend = Globalize::Backend::Chain.new(Globalize::Backend::Static.new)

results in:
#<NoMethodError: undefined method reload!' for #<Globalize::Backend::Chain:0xb6935bf0>> (...)/vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb:80:in reload!'

[PATCH] Globalize2 broken in Rails 3.0 RC

In Rails 3.0RC methods "class_name" was removed from ActiveRecord::Base. Globalize2 is broken because of that (method "translates" does not work). Here is my short workaround (I just copy-pasted implementation of removed class_method into globalize/active_record.rb file)


# file  globalize2/lib/globalize/active_record.rb
# ...
# BEGIN OF PATCH
class_name = table_name[table_name_prefix.length..-(table_name_suffix.length + 1)].camelize
class_name = class_name.singularize if pluralize_table_names
# END OF PATCH
has_many :translations, :class_name  => translation_class.name,
                        :foreign_key => class_name.foreign_key,
                        :dependent   => :delete_all,
                        :extend      => HasManyExtensions
# ...

Translated models - validation works only for current locale

validations only work for the current locale, but I think it should work for all locales

in model

translates :description
validates_length_of :description, :maximum=>6, :allow_nil => true

usecase

I18n.locale = 'de'
record.description = "this string is too long for this field"
record.save # fails
I18n.locale = 'en'
record.save # doesn't fail, but should!

Dirty objects doesn't work completely

When you want to use _was dirty method on a translated field, it gives no method error in first run, nil on second run and correct value for a third run as below:

c = Category.last

c.name_was
NoMethodError: undefined method `name_was' 
c.name
=>"Category Name"
c.name_was
NoMethodError: undefined method `name_was' 
c.name = "New Name"
=> "New Name"
c.name_was
=> nil
c.save
=> true
c.name_was
=> "New Name"

Issues when using rails formbuilder

We ran into a problem where the rails formbuilder wasn't pulling out our translated attributes. We finally tracked this down to the method #{attr}_before_type_cast, which wasn't returning the translated field.

Here is the patch and test that fixed the problem for us, hope it helps!

http://gist.github.com/107265

delete globalize translations on record destroy

it would be nice if the translation records would get deleted with the parent record.
adding a :dependent option, for the has_many association created, should be enought:

      def translates(*attr_names)
        ...

        # Only set up once per class
        unless included_modules.include? InstanceMethods
          ...

          self.globalize_proxy = ...
          has_many :globalize_translations, :class_name => globalize_proxy.name, :extend => Extensions, :dependent => :delete_all # delete should be enought

          after_save ...
        end

        ...
      end

with globalize2, combining associations and named_scopes is not possible

To make it simple and quick: if a model has attributes translated using globalize2, belongs_to :someclass and has a named_scope, the three don't play nice, throwing
ArgumentError: wrong number of arguments (2 for 1)
from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:340:in `respond_to?'

So, for instance if we have

class Category
  has_many :products
end

class Product
  belongs_to :category
  translates :title, :description
  named_scope :available, :conditions => {:available => true}
end

And then:
c = Category.first
c.products # works flawlessly
c.products.available # throws wrong number of arguments

Commenting out translates clause of course fixes the issue, but I want my models to work using globalize2 ;)

makes sure interpolation does not break even with False as string

there's a test with this issue's "title" name however it's not testing what it should be.

it seems that the current implementation of the static backend is not compatible with the default simple backend in cases where the I18n.translate should return a true or false value, I have fixed the backend and added these tests :

http://gist.github.com/161328

the static backend fix and the tests are available in my globalize2 fork :

http://github.com/kares/globalize2/tree/master

Named_scope doesn't work since version 0.2.0

After upgrading Globalize2 plugin to version 0.2.0 this code stoped work:

class Category < ActiveRecord::Base
  attr_accessible :name
  translates :name

  default_scope :include => :globalize_translations

  named_scope :top_categories, {
                            :conditions => {:category_translations => {:locale => I18n.locale}},
                            :order => 'name asc'}
end

How can I manage named_scopes now? Please, help me! My Rails version is 2.3.5.

deserialize translated values

I got serialized objects stored in the translation table but when i access to them they are considered as String and there are not deserialized anymore.

(YAML storage)

I'm obliged to do YAML::load, but i would like to how i can get my values deserialized as before.

not raising missing translations exception

via http://groups.google.com/group/rails-i18n/browse_thread/thread/44df06eed78c0516

Hi,

I am using Globalize2 in some projects, and recently noticed that I
don't get any notices that there are missing translations (no text
show up, and no entry in the missing translations log).
I suspect that it is these lines in the static.rb file that is to blame:

    translation(result, attrs)

translation(result, attrs) || raise(I18n::MissingTranslationData.new(locale, key, options))

Now I wonder if there is a reason for this, and if there is another
way that is more preferred or if it was just something that was
overlooked? (also, if I change it back, will there be something else
that will break that is depending on this new behaviour)

Regards,
Jimmy

Create a migration script for Globalize1 / Rails 2.1 users

At the moment installing Globalize2 pretty much cripples an application with Globalize1 db and cannot be easily migrated (relevant fields/columns are not accessible).

A migration script (rake task?) that'd seamlessly transfer existing Globalize1 translations (minus the default records) to a Globalize2 translations -- would be great.

Temporary disable using translations

Would be nice to have a helper which temporally disabled using translations when operating on a model which has translations but performing an action which does not involve the translations (example, setting the position column on a few records in a model)

Problem passing migrations globalize2

If you have a migration that were putting some data in the db and you have another migration creating the translation table after.

When you will create another db and you will run your migrations it will not work because it will tell you that the translation table has not been created.

So I will have to create another migration that creates datas after the translation tables are created.

Globalize doesn't allow migration to run

I'm picking a project where there's a model called Project with three translated fields. These fields were translated at different times, so there are two migrations, one for two fields and one for another field. When I try to run the migrations I get a complaint about a missing field, which is in a later migration effectively having me stuck, no able to migrate (without having to change the code in a way that will fail later).

==  AddProjectTranslations: migrating =========================================
rake aborted!
An error has occurred, this and all later migrations canceled:

Missing translated field url

i18n content, not UI

Not really an issue. Is there a best practice on how to use globalize2 in a i18n backend enabled ui? e.g. have the rails i18n set to :de for the ui but want to work on the :en model locale ...

create_translation_table! helper ignores config.active_record.table_name_prefix

Rails::Initializer.run do |config|
...
config.active_record.table_name_prefix = 'myprefix_'
...
end

Rails migrations work well.

Ex. rails migration for model Page creates myprefix_pages.

Globalize2 helper ignores table_name_prefix and creates page_translations (needed: myprefix_page_translations)

That miss cause this error:
Mysql::Error: Table 'my_db.myprefix_page_translations' doesn't exist: SELECT * FROM myprefix_page_translations WHERE (myprefix_page_translations.page_id = 27 AND (myprefix_page_translations.locale IN ('en','root')))

ty

Warning regarding class_name

I'm getting this warning with globalize2:

 DEPRECATION WARNING: ActiveRecord::Base#class_name is deprecated and will be removed in Rails 2.3.9. (called from translates at /Users/pupeno/.rvm/gems/ruby-1.8.7-p302@lemonfrog/gems/globalize2-0.2.1/lib/globalize/active_record.rb:57)

rake test failed in rails 3

usermatoMacBook-Pro:globalize2 qichunren$ rake test
(in /Users/qichunren/github/globalize2)
/Users/qichunren/.rvm/rubies/ruby-1.9.2-p0/bin/ruby -I"lib:lib" "/Users/qichunren/.rvm/gems/ruby-1.9.2-p0/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/active_record/fallbacks_test.rb" "test/active_record/migration_test.rb" "test/active_record/sti_translated_test.rb" "test/active_record/translates_test.rb" "test/active_record/translation_class_test.rb" "test/active_record_test.rb" "test/i18n/missing_translations_test.rb"
/Users/qichunren/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0.beta1/lib/active_record/base.rb:1048:in method_missing': undefined methodclass_inheritable_accessor' for Post(Table doesn't exist):Class (NoMethodError)
from /Users/qichunren/github/globalize2/lib/globalize/active_record.rb:47:in translates' from /Users/qichunren/github/globalize2/test/data/models.rb:11:inclass:Post'
from /Users/qichunren/github/globalize2/test/data/models.rb:10:in <top (required)>' from <internal:lib/rubygems/custom_require>:29:inrequire'
from internal:lib/rubygems/custom_require:29:in require' from /Users/qichunren/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:237:inblock in require'
from /Users/qichunren/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:223:in block in load_dependency' from /Users/qichunren/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:639:innew_constants_in'
from /Users/qichunren/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:223:in load_dependency' from /Users/qichunren/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.1.0.beta1/lib/active_support/dependencies.rb:237:inrequire'
from test/active_record/fallbacks_test.rb:2:in <top (required)>' from /Users/qichunren/.rvm/gems/ruby-1.9.2-p0/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5:inload'
from /Users/qichunren/.rvm/gems/ruby-1.9.2-p0/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5:in block in <main>' from /Users/qichunren/.rvm/gems/ruby-1.9.2-p0/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5:ineach'
from /Users/qichunren/.rvm/gems/ruby-1.9.2-p0/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5:in `

'
rake aborted!
Command failed with status (1): [/Users/qichunren/.rvm/rubies/ruby-1.9.2-p0...]

(See full trace by running task with --trace)
usermatoMacBook-Pro:globalize2 qichunren$

fallbacks method not there?!

Hello,

i am quite new to Globalize2. I've been doing my translations until now using the integrated i18n rails stuff. So i used the usual language files. Now i badly need to do all stuff in a database.
I have installed the joshmh/globalize2 plugin and also managed to get some results.

The problem comes when using 'fallbacks' method.
Is fails with an error:
/config/initializers/globalize.rb:1: undefined method fallbacks' for I18n:Module (NoMethodError) from /usr/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:145:inload_without_new_constant_marking'
from /usr/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:145:in `load'.....etc.

What I have and works withour problems, you can see here:
post.rb model:
class Post < ActiveRecord::Base
translates :title, :text
end

post controller:
class PostsController < ApplicationController
def index
@posts = Post.find(:all)
end
end

index.html.erb:
<%- @posts.each do |post| %>
Title: <%= post.title %>

Text: <%= post.text %>


<%- end %>

As soon as I want to set the fallsbacks ,
<% I18n.fallbacks[:de] %>
it crashes with the above error.

So, why do I get the translations correctly from the database (which tells me the plugin is working somehow), but the method does not exist? It's quite strange. :-(
Can somebody help me out with this?

Regards,
Chris

validations only work for current locale, not for translations added using set_translations

when you define a 'validates_presence_of :something' on a model, this is only checked for translations in the current locale but not for any other translations you set using 'set_translations':

test "validates_presence_of using set_translations" do
Validatee.class_eval { validates_presence_of :string }
assert !Validatee.new.valid?
assert Validatee.new(:string => 'foo').valid?
### The following fails
assert_nothing_raised do
Validatee.new(:string => 'bar').set_translations(:fr => { :string => '' })
end
end

One solution is to set the validations on the translation class itself:

test "" do
Validatee.translation_class.class_eval do
validates_presence_of :string
end

I18n.locale = :en
validatee = Validatee.new(:string => "a string")
assert validatee.valid?
validatee.set_translations(:nl => {:string => ''}) rescue nil # we need to recsue as set_translations uses update_attributes!
assert !validatee.valid? ### this works

end

Work as a gem

Hello,

Can you make it possible and easy/documented to use globalize2 as a gem? Maybe with something like Globalize2.init that one could put in a Rails initializer once the gem has been loaded?

Thanks.

belongs_to association and reflection

I'm using Rails 2.3.4 and latest version of Globalize2.
Don't know how to describe the issue, so here are the facts.
In globalize2/lib/globalize/model/active_record.rb on line 16:
belongs_to "#{klass.name.underscore.gsub('/', '')}".intern
But SomeModelTranslation.reflect_on_all_associations returns []
If I add
self.globalize_proxy.belongs_to "#{self.name.underscore.gsub('/', '
')}".intern
after line 27 in globalize2/lib/globalize/model/active_record/translated.rb, or simply envoke
SomeModelTranslation.belongs_to :some_model
then association builds properly.

globalize2 and serialize

It seems like if you have a serialized field declared in your model that is being stored in the translation table when you try accessing to it it doesn't deserialize and you get a String instead of an Array.

Would be great if globalize2 could handle it. The serialize function doesn't work anymore. :/.

I got to put everywhere YAML::load around the returned String to make it work again.

fallbacks_test.rb never runs

The tests are there, but the condition to run them is never true. I added:

I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)

And there are 4 failures. Obviously it's very hard to enable Fallbacks within a test suite since it's an included module. However these tests should be run, and I'm working on functionality that needs specific testing in fallbacks mode, so it'd be nice to work out some kind of automated testing here... maybe separate rake tasks?

Broken session with Globalize::Translation::Static

Globalize2 uses Globalize::Translation::Static instead of String. So, if you save such translated string in session (flash[:notice] = t :some_message) and then try to use this session in another Rails App without installed Globalize2 you'll got and Error.

And second, instead of "my message" it will be stored as "full_qualified_class_name, version, bla-bla my message". And this is also problem because session size is limited.

it will:

Attribute query methods

Hi,

the attribute query methods like "object.attribute?" are not working with globalize2. I have to use the blank? method instead. Shouldn't there be a compatibility layer?

Regards, Marek Kralewski

Quering on a model with translated attributes

Hi!

How can I query a model where an attribute is translated with globalize2. I have for example this line, and the attribute name is in the country_translations table:

I18n.locale = :de
@countries = Country.scoped
@countries.where(:name => '[Some country name]')

This gives me an error: ActiveRecord::StatementInvalid (No attribute named name exists for table countries): ...

Thx

Translation objects after updates does not work

the following gave me some problems :

article = Article.find(1)
article.title
     ==> Globalize::Translation::Attribute

article.update_attributes(params[:acticle])
article.title
     ==> String

Problems for view after update.

:text does not working

Hi,
i have migration with Post.create_translation_table! :title => :string, :body => :text
and model with translates :title, :body
and body is returning nil on read access (but writes ok). Whats wrong?

find_by_*! don works (find_by_* - works fine)

Example:

>> Product.find_by_name('iusto nihil sequi debitis saepe')
=> Product id: 1, model_id: 1, name: "aaaa", description: "aaaa", image_file_name: nil, image_content_type: nil, image_file_size: nil, image_updated_at: nil, sku: "LOrTusgeDTI1xQ==", production_status: nil, weight: 0, width: 0, length: 0, height: 0, created_at: "2010-01-15 10:22:39", updated_at: "2010-01-15 10:22:55">
>> Product.find_by_name!('iusto nihil sequi debitis saepe')
ActiveRecord::RecordNotFound: Couldn't find Product with name = iusto nihil sequi debitis saepe
>> I18n.locale                                                                                                                                                                               
=> :en                                                                                                                                                                                       
>> p = Product.find_by_name!('aaaa')
=> Product id: 1, model_id: 1, name: "aaaa", description: "aaaa", image_file_name: nil, image_content_type: nil, image_file_size: nil, image_updated_at: nil, sku: "LOrTusgeDTI1xQ==", production_status: nil, weight: 0, width: 0, length: 0, height: 0, created_at: "2010-01-15 10:22:39", updated_at: "2010-01-15 10:22:55">
>> p.name
=> "iusto nihil sequi debitis saepe"
>> I18n.locale = :pl
=> :pl
>> p.name
=> "aaaa"

it looks like when you try to find with ! - it looks for the last translation that you have saved - but not for currect setted

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.