rails_db_localize 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b871138a311b81b19fe496d8ee8e5a24728d0d2d
4
- data.tar.gz: 9fef4a09569e4063bb8aa9cc102a948306f5eb01
3
+ metadata.gz: 6dddf4c074ccd2e53d6ae27b8f6894b3036760a8
4
+ data.tar.gz: 5093a12848cb94da0b88ffba1996f83de8bcfc82
5
5
  SHA512:
6
- metadata.gz: 25dff5f05e0d1c9d5d4a594c6317f60a869e25273a05cf42c272c6676f80d013a5304b303e0af626d38a161eb3de3821a618a0d6c466ecaed6997a338c00144a
7
- data.tar.gz: 46dd58fb5744d3d084ac2c403a61a626456d00917e1ad552574dcf894b7f05fb1c59ca480325876b8f7e752db1f1b486199e397facd47c30d055cd9ea3f6a880
6
+ metadata.gz: 1a1b65ecb96440a0135817ed14dcb1a2560da07422d084007af852ba617ee994559586b0a5b01c05ee7d566ba8dd9d21386d29590b295f121425bdfc441dabd8
7
+ data.tar.gz: fe7630b9035ac83ee4565bbcc71e12e00d14084e9cac2d121d707290a6b7b7fecbcaf56e30b6e62f6d72f9d5709fa175df315fda6c73a9aba6ca553bb3d9820a
data/README.md CHANGED
@@ -9,21 +9,20 @@ The most annoying part is globalize3 create a table for each object you want to
9
9
 
10
10
  I've made this gem with theses rules in head:
11
11
 
12
- ## 1/ Translation just in time.
12
+ ### 1/ Translation just in time.
13
13
 
14
14
  You don't need to think about translation in your project until you begin the translation process.
15
15
  `rails_db_localize` doesn't modify your database schematic but instead just add a layer on it.
16
16
 
17
- ## 2/ One table to bring them all.
17
+ ### 2/ One table to bring them all.
18
18
 
19
19
  `rails_db_localize` add only one table to your project. All your translations are stored inside this table.
20
20
  This allow you to make without any pain a tool to manage a team of traductors for example.
21
21
 
22
22
  Since everything is in the same table, one controller is enough to manage the translation process!
23
- About performance, `rails_db_localize` use some optimisations for fetching the rows (caching and hashing system).
23
+ About performance, `rails_db_localize` use some optimizations for fetching the rows (caching and hashing system).
24
24
 
25
-
26
- ## 3/ Only one query for all your translations
25
+ ### 3/ Only one query for all your translations
27
26
 
28
27
  Thanks to the caching system, `rails_db_localize` need only one query to retrieve all the translations of your current view (see below)
29
28
 
@@ -77,7 +76,7 @@ or:
77
76
  model.name_translated = "Name in french", :fr
78
77
  ```
79
78
 
80
- # SQL Optimisation
79
+ # SQL Optimization
81
80
 
82
81
  To avoid N+1 requests, please use the preloader on every array of models you want to use:
83
82
 
@@ -86,11 +85,49 @@ To avoid N+1 requests, please use the preloader on every array of models you wan
86
85
  @categories = Category.all
87
86
  #Only one request per preload_translations_for call
88
87
  preload_translations_for(@translatables, @categories)
88
+
89
+ #If you have only one set of data, you can use the model method:
90
+ @categories.preload_translations
89
91
  ```
90
92
 
93
+ # Other features
94
+
95
+ Each model having at least a translated field can use `missing_translation` and `having_translation`
96
+
97
+ Theses methods allow you to filters your models if they are translated or not.
98
+
99
+ ### Blog case:
100
+
101
+ You have a blog with articles in two languages but you don't translate all articles.
102
+ To show articles from the current langage selected on your blog, you can use:
103
+
104
+ ```ruby
105
+ def index
106
+ @articles = Articles.having_translation(I18n.locale).all
107
+ end
108
+ ```
109
+
110
+ ### Other case:
111
+
112
+ You have a team of translators:
113
+ - One can translate from english to french
114
+ - Another one can translate from french to spanish
115
+
116
+ You just have to filters the articles in your translation tool like this:
117
+ ```ruby
118
+ Articles.having_translation(translator.from_language).missing_translation(translator.to_language)
119
+ ```
120
+ Create two users with role translator with from/to_language "en/fr" and "fr/es". Et voilà!
121
+
91
122
  # Changelog
92
123
 
93
- 0.1 - First commit
124
+ ## 0.2
125
+
126
+ Add methods `having_translation`, `missing_translation` and `preload_translation`
127
+
128
+ ## 0.1
129
+
130
+ First commit
94
131
 
95
132
  # Licensing
96
133
 
@@ -15,11 +15,18 @@ class RailsDbLocalize::Translation < ActiveRecord::Base
15
15
 
16
16
  before_validation :set_compound_key
17
17
 
18
+
19
+
18
20
  def self.generate_ck resource_type, resource_id
19
- #Keep it 32bits.
20
- [resource_type.to_s.underscore, resource_id].join("|").hash & 0x7fffffff
21
+ hash_long = [resource_type.to_s.underscore, resource_id].join("|").chars.map(&:ord).inject(5381) do |h, v|
22
+ h = ((h<<5)+h)+v
23
+ end
24
+
25
+ #Keep it signed 32bits.
26
+ hash_long & 0x7fffffff
21
27
  end
22
28
 
29
+
23
30
  def self.get_untranslated model, field, lang
24
31
  model.where("id NOT IN (?)",
25
32
  [-1, *RailsDbLocalize::Translation.where(resource_type: k.to_s, lang: lang, field: field).pluck(:resource_id).uniq]
@@ -7,6 +7,38 @@ class ActiveRecord::Base
7
7
  @__rdbl_translations = true
8
8
  # Register it mostly to remove the translations once you delete an object
9
9
  self.has_many :translations, as: :resource, dependent: :destroy
10
+
11
+ scope :__rails_db_translations_sub_query, lambda{ |lang|
12
+ ttable = RailsDbLocalize::Translation.arel_table.name
13
+ number_of_fields_to_translates = RailsDbLocalize.schema[self.to_s].count
14
+
15
+ # We can unscope, but problems tend to appears
16
+ # with some gems like paranoid.
17
+ table = respond_to?(:klass) ? table.klass : self
18
+
19
+ table.select(:id).joins("INNER JOIN \"#{ttable}\"
20
+ ON (\"#{ttable}\".resource_id = \"#{arel_table.name}\".id
21
+ AND \"#{ttable}\".resource_type = '#{to_s}')")
22
+ .group(:resource_type, :resource_id)
23
+ .having("COUNT(*) == #{number_of_fields_to_translates}")
24
+ .where(:"rails_db_localize_translations.lang" => lang)
25
+ }
26
+
27
+ # Return all rows with missing translation for a selected language.
28
+ self.scope :missing_translation, lambda{ |lang|
29
+ where("\"#{arel_table.name}\".id NOT IN (#{__rails_db_translations_sub_query(lang).to_sql})")
30
+ }
31
+
32
+ # Return all rows with translation OK for a selected language.
33
+ self.scope :having_translation, lambda{ |lang|
34
+ where("\"#{arel_table.name}\".id IN (#{__rails_db_translations_sub_query(lang).to_sql})")
35
+ }
36
+
37
+ def self.preload_translations
38
+ RailsDbLocalize::TranslationCache.instance.prefetch_collections(self)
39
+ self
40
+ end
41
+
10
42
  end
11
43
 
12
44
  fields.each do |field|
@@ -20,6 +52,11 @@ class ActiveRecord::Base
20
52
  # I should really learn how to use the Reflection helpers in ActiveRecord, because
21
53
  # ruby eval is not the most readable stuff... :o)
22
54
  self.class_eval <<-CODE, __FILE__, __LINE__ + 1
55
+ def #{field}_translated_exists?(lang=nil)
56
+ lang ||= I18n.locale
57
+ !!RailsDbLocalize::TranslationCache.instance.get_translation_for(self.class, self.id, "#{field}", lang, nil )
58
+ end
59
+
23
60
  def #{field}_translated (lang=nil)
24
61
  lang ||= I18n.locale
25
62
  RailsDbLocalize::TranslationCache.instance.get_translation_for(self.class, self.id, "#{field}", lang, self.#{field} )
@@ -60,7 +60,7 @@ public
60
60
  encache RailsDbLocalize::Translation.where("compound_key IN (?)", in_clause).pluck(:resource_type, :resource_id, :field, :lang, :content)
61
61
  end
62
62
 
63
- def get_translation_for model_class, model_id, field, lang, default
63
+ def get_translation_for model_class, model_id, field, lang, default=nil
64
64
  ck = RailsDbLocalize::Translation.generate_ck(model_class, model_id)
65
65
 
66
66
  if @cache[:cks][ck]
@@ -1,3 +1,3 @@
1
1
  module RailsDbLocalize
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
Binary file