rails_db_localize 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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