friendly_id-globalize 1.0.0.alpha2 → 1.0.0.alpha4

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
- SHA1:
3
- metadata.gz: c240c7dc5d34b3afb7338ae100c7202f04d73e96
4
- data.tar.gz: f5655d526ff831df27bad81a74699c824123ffb0
2
+ SHA256:
3
+ metadata.gz: 3c63abb7940af7e1cfb45dc6bcc7203699a4993ee7fb7d2bda9a8f788c2710a2
4
+ data.tar.gz: c87d245f950ef8da97062015d6bd05be41e4c2466953d0dcf689077d1a160839
5
5
  SHA512:
6
- metadata.gz: a6b36a173d89897737d18071f84a55eddeeb9edf1afaf61cec54b703a9a2975e1e65ab632486a5873bd707ab994a366c2d6105bbe15fb1008c8b455de332f5a9
7
- data.tar.gz: 07d69a9ec4616a7ba1da6f744cae485b6c1bb7a75abd5b379334492992f1d0a829de35b3dd78454f87193663488b00dcaf77f3d5ef5636fc1ac64b967c50a53b
6
+ metadata.gz: 70275b9abdc134b05ec8e0836b0a22894f02faa18304f8962231bcb55052312dde373d115b2ee16aeed1e33220bb063776535c3911d6ec3a56cae30f13079f52
7
+ data.tar.gz: 94721821b35d7ad98055e76498ac403d964af9ad03a26daf982bf2e1bc4081e650749f4b5d6ca481260a198d04fc1970c37b98a09775c35406145c7c800e7523
data/README.md CHANGED
@@ -3,6 +3,12 @@
3
3
  [Globalize](https://github.com/globalize/globalize) support for
4
4
  [FriendlyId](https://github.com/norman/friendly_id).
5
5
 
6
+ ### Installation
7
+ ```ruby
8
+ gem 'friendly_id-globalize'
9
+ rails generate friendly_id_globalize
10
+ ```
11
+
6
12
  ### Translating Slugs Using Globalize
7
13
  The `FriendlyId::Globalize Globalize` module lets you use
8
14
  [Globalize](https://github.com/globalize/globalize) to translate slugs. This
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
16
16
 
17
17
  s.required_ruby_version = '>= 1.9.3'
18
18
 
19
- s.add_dependency 'friendly_id', '~> 5.1.0', '< 6.0'
19
+ s.add_dependency 'friendly_id', '>= 5.1.0', '< 6.0'
20
20
  s.add_development_dependency 'minitest'
21
21
  s.add_development_dependency 'yard'
22
22
  s.add_development_dependency "globalize"
@@ -1,5 +1,5 @@
1
1
  module FriendlyId
2
2
  module Globalize
3
- VERSION = '1.0.0.alpha2'
3
+ VERSION = '1.0.0.alpha4'
4
4
  end
5
5
  end
@@ -7,7 +7,7 @@ module FriendlyId
7
7
  == Translating Slugs Using Globalize
8
8
 
9
9
  The {FriendlyId::Globalize Globalize} module lets you use
10
- Globalize[https://github.com/svenfuchs/globalize3] to translate slugs. This
10
+ Globalize[https://github.com/globalize/globalize] to translate slugs. This
11
11
  module is most suitable for applications that need to be localized to many
12
12
  languages. If your application only needs to be localized to one or two
13
13
  languages, you may wish to consider the {FriendlyId::SimpleI18n SimpleI18n}
@@ -85,7 +85,7 @@ current locale:
85
85
 
86
86
  def set_friendly_id(text, locale = nil)
87
87
  ::Globalize.with_locale(locale || ::Globalize.locale) do
88
- set_slug normalize_friendly_id(text)
88
+ super_set_slug normalize_friendly_id(text)
89
89
  end
90
90
  end
91
91
 
@@ -94,12 +94,8 @@ current locale:
94
94
  end
95
95
 
96
96
  def set_slug(normalized_slug = nil)
97
- if self.translations.size > 1
98
- self.translations.map(&:locale).each do |locale|
99
- ::Globalize.with_locale(locale) { super_set_slug(normalized_slug) }
100
- end
101
- else
102
- ::Globalize.with_locale(::Globalize.locale) { super_set_slug(normalized_slug) }
97
+ (self.translations.map(&:locale).presence || [::Globalize.locale]).each do |locale|
98
+ ::Globalize.with_locale(locale) { super_set_slug(normalized_slug) }
103
99
  end
104
100
  end
105
101
 
@@ -107,9 +103,8 @@ current locale:
107
103
  if should_generate_new_friendly_id?
108
104
  candidates = FriendlyId::Candidates.new(self, normalized_slug || send(friendly_id_config.base))
109
105
  slug = slug_generator.generate(candidates) || resolve_friendly_id_conflict(candidates)
110
- translation.slug = slug
106
+ translation.send("#{friendly_id_config.slug_column}=", slug)
111
107
  end
112
108
  end
113
109
  end
114
110
  end
115
-
@@ -0,0 +1,142 @@
1
+ module FriendlyId
2
+
3
+ =begin
4
+
5
+ ## History: Avoiding 404's When Slugs Change
6
+
7
+ FriendlyId's {FriendlyId::History History} module adds the ability to store a
8
+ log of a model's slugs, so that when its friendly id changes, it's still
9
+ possible to perform finds by the old id.
10
+
11
+ The primary use case for this is avoiding broken URLs.
12
+
13
+ ### Setup
14
+
15
+ In order to use this module, you must add a table to your database schema to
16
+ store the slug records. FriendlyId provides a generator for this purpose:
17
+
18
+ rails generate friendly_id_globalize
19
+ rake db:migrate
20
+
21
+ This will add a table named `friendly_id_slugs`, used by the {FriendlyId::Slug}
22
+ model.
23
+
24
+ ### Considerations
25
+
26
+ Because recording slug history requires creating additional database records,
27
+ this module has an impact on the performance of the associated model's `create`
28
+ method.
29
+
30
+ ### Example
31
+
32
+ class Post < ActiveRecord::Base
33
+ extend FriendlyId
34
+ friendly_id :title, :use => :history
35
+ end
36
+
37
+ class PostsController < ApplicationController
38
+
39
+ before_filter :find_post
40
+
41
+ ...
42
+
43
+ def find_post
44
+ @post = Post.find params[:id]
45
+
46
+ # If an old id or a numeric id was used to find the record, then
47
+ # the request path will not match the post_path, and we should do
48
+ # a 301 redirect that uses the current friendly id.
49
+ if request.path != post_path(@post)
50
+ return redirect_to @post, :status => :moved_permanently
51
+ end
52
+ end
53
+ end
54
+ =end
55
+ module History
56
+
57
+ def self.setup(model_class)
58
+ model_class.instance_eval do
59
+ friendly_id_config.use :slugged
60
+ friendly_id_config.finder_methods = FriendlyId::History::FinderMethods
61
+ if friendly_id_config.uses? :finders
62
+ relation.class.send(:include, friendly_id_config.finder_methods)
63
+ if ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 2
64
+ model_class.send(:extend, friendly_id_config.finder_methods)
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ # Configures the model instance to use the History add-on.
71
+ def self.included(model_class)
72
+ model_class.class_eval do
73
+ has_many :slugs, -> {order(Slug.arel_table[:id].desc)},
74
+ as: :sluggable,
75
+ dependent: :destroy,
76
+ class_name: Slug.to_s
77
+
78
+ after_save :create_slug
79
+ end
80
+ end
81
+
82
+ module FinderMethods
83
+ include ::FriendlyId::FinderMethods
84
+
85
+ def exists_by_friendly_id?(id)
86
+ joins(:slugs, :translations).where(translation_class.arel_table[friendly_id_config.query_field].eq(id)).exists? || joins(:slugs).where(slug_history_clause(id)).exists?
87
+ end
88
+
89
+ private
90
+
91
+ def first_by_friendly_id(id)
92
+ matching_record = where(friendly_id_config.query_field => id).first
93
+ matching_record || slug_table_record(id)
94
+ end
95
+
96
+ def slug_table_record(id)
97
+ select(quoted_table_name + '.*').joins(:slugs).where(slug_history_clause(id)).order(Slug.arel_table[:id].desc).first
98
+ end
99
+
100
+ def slug_history_clause(id)
101
+ Slug.arel_table[:sluggable_type].eq(base_class.to_s).and(Slug.arel_table[:slug].eq(id)).and(Slug.arel_table[:locale].eq(::Globalize.locale))
102
+ end
103
+ end
104
+
105
+ private
106
+
107
+ # If we're updating, don't consider historic slugs for the same record
108
+ # to be conflicts. This will allow a record to revert to a previously
109
+ # used slug.
110
+ def scope_for_slug_generator
111
+ relation = super
112
+ return relation if new_record?
113
+ relation = relation.merge(Slug.where('sluggable_id <> ?', id))
114
+ if friendly_id_config.uses?(:scoped)
115
+ relation = relation.where(Slug.arel_table[:scope].eq(serialized_scope))
116
+ end
117
+ relation
118
+ end
119
+
120
+ def create_slug
121
+ translations.map(&:locale).each do |locale|
122
+ ::Globalize.with_locale(locale) { super_create_slug(locale) }
123
+ end
124
+ end
125
+
126
+ def super_create_slug(locale)
127
+ return unless friendly_id
128
+ return if slugs.where(locale: locale).first.try(:slug) == friendly_id
129
+ # Allow reversion back to a previously used slug
130
+ relation = slugs.where(slug: friendly_id, locale: locale)
131
+ if friendly_id_config.uses?(:scoped)
132
+ relation = relation.where(:scope => serialized_scope)
133
+ end
134
+ relation.delete_all
135
+ slugs.create! do |record|
136
+ record.slug = friendly_id
137
+ record.locale = locale
138
+ record.scope = serialized_scope if friendly_id_config.uses?(:scoped)
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,11 @@
1
+ class AddLocaleToFriendlyIdSlugs < ActiveRecord::Migration
2
+ def change
3
+ add_column :friendly_id_slugs, :locale, :string, length: 2, null: :false, after: :scope
4
+
5
+ remove_index :friendly_id_slugs, [:slug, :sluggable_type]
6
+ add_index :friendly_id_slugs, [:slug, :sluggable_type, :locale], length: { slug: 140, sluggable_type: 50, locale: 2 }
7
+ remove_index :friendly_id_slugs, [:slug, :sluggable_type, :scope]
8
+ add_index :friendly_id_slugs, [:slug, :sluggable_type, :scope, :locale], length: { slug: 70, sluggable_type: 50, scope: 70, locale: 2 }, unique: true, name: :index_friendly_id_slugs_uniqueness
9
+ add_index :friendly_id_slugs, :locale
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ require 'rails/generators'
2
+ require "rails/generators/active_record"
3
+
4
+ # This generator adds a migration for the {FriendlyId::History
5
+ # FriendlyId::History} addon.
6
+ class FriendlyIdGlobalizeGenerator < ActiveRecord::Generators::Base
7
+ # ActiveRecord::Generators::Base inherits from Rails::Generators::NamedBase which requires a NAME parameter for the
8
+ # new table name. Our generator always uses 'friendly_id_slugs', so we just set a random name here.
9
+ argument :name, type: :string, default: 'random_name'
10
+
11
+ class_option :'skip-migration', :type => :boolean, :desc => "Don't generate a migration for the slugs table"
12
+
13
+ source_root File.expand_path('../../friendly_id', __FILE__)
14
+
15
+ # Copies the migration template to db/migrate.
16
+ def copy_files
17
+ return if options['skip-migration']
18
+ migration_template 'migration.rb', 'db/migrate/add_locale_to_friendly_id_slugs.rb'
19
+ end
20
+ end
@@ -22,14 +22,14 @@ ActiveRecord::Migration.verbose = false
22
22
  FriendlyIdGlobalizeTest.up
23
23
 
24
24
  class Article < ActiveRecord::Base
25
- translates :slug, :title, fallbacks_for_empty_translations: true
25
+ translates :my_slug, :title, fallbacks_for_empty_translations: true
26
26
  accepts_nested_attributes_for :translations
27
27
 
28
28
  extend FriendlyId
29
- friendly_id :title, :use => [:slugged, :globalize]
29
+ friendly_id :title, :use => :globalize, :slug_column => 'my_slug'
30
30
  end
31
31
 
32
- Article.create_translation_table! :slug => :string, :title => :string
32
+ Article.create_translation_table! :my_slug => :string, :title => :string
33
33
 
34
34
  class Module
35
35
  def test(name, &block)
@@ -77,21 +77,25 @@ class GlobalizeTest < MiniTest::Unit::TestCase
77
77
  transaction do
78
78
  article = Article.create!(:title => "War and Peace")
79
79
  article.set_friendly_id("Guerra y paz", :es)
80
+ article.set_friendly_id("Guerra e pace", :it)
80
81
  article.save!
81
82
  found_article = Article.friendly.find('war-and-peace')
82
83
  I18n.with_locale(:es) { assert_equal "guerra-y-paz", found_article.friendly_id }
83
84
  I18n.with_locale(:en) { assert_equal "war-and-peace", found_article.friendly_id }
85
+ I18n.with_locale(:it) { assert_equal "guerra-e-pace", found_article.friendly_id }
84
86
  end
85
87
  end
86
88
 
87
89
  test "should set all friendly ids for each nested translation" do
88
90
  transaction do
89
91
  article = Article.create!(translations_attributes: {
90
- xx: { :title => "Guerra e pace", locale: 'it' },
91
- yy: { title: 'Guerre et paix', locale: 'fr' }
92
+ xx: { title: 'Guerra e pace', locale: 'it' },
93
+ yy: { title: 'Guerre et paix', locale: 'fr' },
94
+ zz: { title: 'Guerra y paz', locale: 'es' }
92
95
  })
93
96
  I18n.with_locale(:it) { assert_equal "guerra-e-pace", article.friendly_id }
94
97
  I18n.with_locale(:fr) { assert_equal "guerre-et-paix", article.friendly_id }
98
+ I18n.with_locale(:es) { assert_equal "guerra-y-paz", article.friendly_id }
95
99
  end
96
100
  end
97
101
 
@@ -110,4 +114,3 @@ class GlobalizeTest < MiniTest::Unit::TestCase
110
114
  end
111
115
  end
112
116
  end
113
-
metadata CHANGED
@@ -1,21 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: friendly_id-globalize
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.alpha2
4
+ version: 1.0.0.alpha4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Norman Clarke
8
8
  - Philip Arndt
9
- autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2015-07-23 00:00:00.000000000 Z
11
+ date: 2025-03-04 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: friendly_id
16
15
  requirement: !ruby/object:Gem::Requirement
17
16
  requirements:
18
- - - "~>"
17
+ - - ">="
19
18
  - !ruby/object:Gem::Version
20
19
  version: 5.1.0
21
20
  - - "<"
@@ -25,7 +24,7 @@ dependencies:
25
24
  prerelease: false
26
25
  version_requirements: !ruby/object:Gem::Requirement
27
26
  requirements:
28
- - - "~>"
27
+ - - ">="
29
28
  - !ruby/object:Gem::Version
30
29
  version: 5.1.0
31
30
  - - "<"
@@ -90,12 +89,14 @@ files:
90
89
  - friendly_id-globalize.gemspec
91
90
  - lib/friendly_id/globalize.rb
92
91
  - lib/friendly_id/globalize/version.rb
92
+ - lib/friendly_id/history.rb
93
+ - lib/friendly_id/migration.rb
94
+ - lib/generators/friendly_id_globalize_generator.rb
93
95
  - test/globalize_test.rb
94
96
  homepage: http://github.com/norman/friendly_id-globalize
95
97
  licenses:
96
98
  - MIT
97
99
  metadata: {}
98
- post_install_message:
99
100
  rdoc_options: []
100
101
  require_paths:
101
102
  - lib
@@ -106,14 +107,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
106
107
  version: 1.9.3
107
108
  required_rubygems_version: !ruby/object:Gem::Requirement
108
109
  requirements:
109
- - - ">"
110
+ - - ">="
110
111
  - !ruby/object:Gem::Version
111
- version: 1.3.1
112
+ version: '0'
112
113
  requirements: []
113
- rubyforge_project:
114
- rubygems_version: 2.4.6
115
- signing_key:
114
+ rubygems_version: 3.6.2
116
115
  specification_version: 4
117
116
  summary: Globalize support for FriendlyId.
118
117
  test_files: []
119
- has_rdoc: