friendly_id 4.0.7 → 4.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog.md CHANGED
@@ -6,6 +6,24 @@ suggestions, ideas and improvements to FriendlyId.
6
6
  * Table of Contents
7
7
  {:toc}
8
8
 
9
+ ## 4.0.8 (2012-08-01)
10
+
11
+ * Name internal anonymous class to fix marshall dump/load error (Jess Brown, Philip Arndt and Norman Clarke).
12
+
13
+ * Avoid using deprecated `update_attribute` (Philip Arndt).
14
+
15
+ * Added set_friendly_id method to Globalize module (Norman Clarke).
16
+
17
+ * autoload FriendlyId::Slug; previously this class was not accessible from
18
+ migrations unless required explicitly, which could cause some queries to
19
+ unexpectedly fail (Norman Clarke).
20
+
21
+ * Fix Mocha load order (Mark Turner).
22
+
23
+ * Minor doc updates (Rob Yurkowski).
24
+
25
+ * Other miscellaneous refactorings and doc updates.
26
+
9
27
  ## 4.0.7 (2012-06-06)
10
28
 
11
29
  * to_param just calls super when no friendly_id is present, to keep the model's
data/Guide.rdoc CHANGED
@@ -480,8 +480,9 @@ languages. If your application only needs to be localized to one or two
480
480
  languages, you may wish to consider the {FriendlyId::SimpleI18n SimpleI18n}
481
481
  module.
482
482
 
483
- In order to use this module, your model must have a slug column and set the
484
- field +slug+ as translable with Globalize:
483
+ In order to use this module, your model's table and translation table must both
484
+ have a slug column, and your model must set the +slug+ field as translatable
485
+ with Globalize:
485
486
 
486
487
  class Post < ActiveRecord::Base
487
488
  translates :title, :slug
@@ -549,4 +550,4 @@ For example:
549
550
  def move_friendly_id_error_to_name
550
551
  errors.messages[:name] = errors.messages.delete(:friendly_id)
551
552
  end
552
- end
553
+ end
data/README.md CHANGED
@@ -128,7 +128,8 @@ should be!
128
128
 
129
129
  ## License
130
130
 
131
- Copyright (c) 2008-2012 Norman Clarke, released under the MIT license.
131
+ Copyright (c) 2008-2012 Norman Clarke and contributors, released under the MIT
132
+ license.
132
133
 
133
134
  Permission is hereby granted, free of charge, to any person obtaining a copy of
134
135
  this software and associated documentation files (the "Software"), to deal in
data/friendly_id.gemspec CHANGED
@@ -6,8 +6,8 @@ require "friendly_id"
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "friendly_id"
8
8
  s.version = FriendlyId::VERSION
9
- s.authors = ["Norman Clarke"]
10
- s.email = ["norman@njclarke.com"]
9
+ s.authors = ["Norman Clarke", "Philip Arndt"]
10
+ s.email = ["norman@njclarke.com", "parndt@gmail.com"]
11
11
  s.homepage = "http://github.com/norman/friendly_id"
12
12
  s.summary = "A comprehensive slugging and pretty-URL plugin."
13
13
  s.rubyforge_project = "friendly_id"
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
17
17
 
18
18
  s.add_development_dependency "railties", "~> 3.2.0"
19
19
  s.add_development_dependency "activerecord", "~> 3.2.0"
20
- s.add_development_dependency "minitest"
20
+ s.add_development_dependency "minitest", "3.2.0"
21
21
  s.add_development_dependency "mocha"
22
22
  s.add_development_dependency "maruku"
23
23
  s.add_development_dependency "yard"
@@ -15,7 +15,7 @@ end
15
15
 
16
16
  gem 'activerecord', '~> 3.0.0'
17
17
  gem 'railties', '~> 3.0.0'
18
- gem 'minitest'
18
+ gem 'minitest', '3.2.0'
19
19
  gem 'mocha'
20
20
  gem 'rake'
21
21
  gem 'globalize3'
@@ -16,7 +16,7 @@ end
16
16
  gem 'activerecord', '~> 3.1.0'
17
17
  gem 'railties', '~> 3.1.3'
18
18
  gem 'ffaker'
19
- gem 'minitest'
19
+ gem 'minitest', '3.2.0'
20
20
  gem 'mocha'
21
21
  gem 'rake'
22
22
  gem 'globalize3'
@@ -16,7 +16,7 @@ end
16
16
  gem 'ffaker'
17
17
  gem 'activerecord', '~> 3.2.0'
18
18
  gem 'railties', '~> 3.2.0'
19
- gem 'minitest'
19
+ gem 'minitest', '3.2.0'
20
20
  gem 'mocha'
21
21
  gem 'rake'
22
22
  gem 'globalize3'
@@ -199,11 +199,9 @@ often better and easier to use {FriendlyId::Slugged slugs}.
199
199
  # on first access. If you're concerned about thread safety, then be sure
200
200
  # to invoke {#friendly_id} in your class for each model.
201
201
  def friendly_id_config
202
- @friendly_id_config or begin
203
- @friendly_id_config = base_class.friendly_id_config.dup.tap do |config|
204
- config.model_class = self
205
- @relation_class = base_class.send(:relation_class)
206
- end
202
+ @friendly_id_config ||= base_class.friendly_id_config.dup.tap do |config|
203
+ config.model_class = self
204
+ @relation_class = base_class.send(:relation_class)
207
205
  end
208
206
  end
209
207
 
@@ -217,13 +215,13 @@ often better and easier to use {FriendlyId::Slugged slugs}.
217
215
  super
218
216
  end
219
217
 
220
- # Gets an anonymous subclass of the model's relation class.
218
+ # Gets (and if necessary, creates) a subclass of the model's relation class.
221
219
  #
222
220
  # Rather than including FriendlyId's overridden finder methods in
223
- # ActiveRecord::Relation directly, FriendlyId adds them to the anonymous
224
- # subclass, and makes #relation return an instance of this class. By doing
225
- # this, we ensure that only models that specifically extend FriendlyId have
226
- # their finder methods overridden.
221
+ # ActiveRecord::Relation directly, FriendlyId adds them to a subclass
222
+ # specific to the AR model, and makes #relation return an instance of this
223
+ # class. By doing this, we ensure that only models that specifically extend
224
+ # FriendlyId have their finder methods overridden.
227
225
  #
228
226
  # Note that this method does not directly subclass ActiveRecord::Relation,
229
227
  # but rather whatever class the @relation class instance variable is an
@@ -240,10 +238,16 @@ often better and easier to use {FriendlyId::Slugged slugs}.
240
238
  # revert back to the old behavior of simply extending
241
239
  # ActiveRecord::Relation.
242
240
  def relation_class
243
- @relation_class ||= Class.new(relation_without_friendly_id.class) do
244
- alias_method :find_one_without_friendly_id, :find_one
245
- alias_method :exists_without_friendly_id?, :exists?
246
- include FriendlyId::FinderMethods
241
+ @relation_class or begin
242
+ @relation_class = Class.new(relation_without_friendly_id.class) do
243
+ alias_method :find_one_without_friendly_id, :find_one
244
+ alias_method :exists_without_friendly_id?, :exists?
245
+ include FriendlyId::FinderMethods
246
+ end
247
+ # Set a name so that model instances can be marshalled. Use a
248
+ # ridiculously long name that will not conflict with anything.
249
+ # TODO: just use the constant, no need for the @relation_class variable.
250
+ const_set('FriendlyIdActiveRecordRelation', @relation_class)
247
251
  end
248
252
  end
249
253
  end
@@ -13,8 +13,9 @@ 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}
14
14
  module.
15
15
 
16
- In order to use this module, your model must have a slug column and set the
17
- field +slug+ as translable with Globalize:
16
+ In order to use this module, your model's table and translation table must both
17
+ have a slug column, and your model must set the +slug+ field as translatable
18
+ with Globalize:
18
19
 
19
20
  class Post < ActiveRecord::Base
20
21
  translates :title, :slug
@@ -31,12 +32,15 @@ Finds will take the current locale into consideration:
31
32
  I18n.locale = :en
32
33
  Post.find("star-wars")
33
34
 
35
+ Additionally, finds will fall back to the default locale:
36
+
37
+ I18n.locale = :it
38
+ Post.find("star-wars")
39
+
34
40
  To find a slug by an explicit locale, perform the find inside a block
35
41
  passed to I18n's +with_locale+ method:
36
42
 
37
- I18n.with_locale(:it) do
38
- Post.find("guerre-stellari")
39
- end
43
+ I18n.with_locale(:it) { Post.find("guerre-stellari") }
40
44
 
41
45
  === Creating Records
42
46
 
@@ -44,12 +48,17 @@ When new records are created, the slug is generated for the current locale only.
44
48
 
45
49
  === Translating Slugs
46
50
 
47
- To translate an existing record's friendly_id, simply change the locale and
48
- assign a value to the +slug+ field:
51
+ To translate an existing record's friendly_id, use
52
+ {FriendlyId::Globalize::Model#set_friendly_id}. This will ensure that the slug
53
+ you add is properly escaped, transliterated and sequenced:
49
54
 
50
- I18n.with_locale(:it) do
51
- post.slug = "guerre-stellari"
52
- end
55
+ post = Post.create :name => "Star Wars"
56
+ post.set_friendly_id("Guerre stellari", :it)
57
+
58
+ If you don't pass in a locale argument, FriendlyId::Globalize will just use the
59
+ current locale:
60
+
61
+ I18n.with_locale(:it) { post.set_friendly_id("Guerre stellari") }
53
62
 
54
63
  =end
55
64
  module Globalize
@@ -67,8 +76,10 @@ assign a value to the +slug+ field:
67
76
  end
68
77
 
69
78
  module Model
70
- def slug=(text)
71
- set_slug(normalize_friendly_id(text))
79
+ def set_friendly_id(text, locale)
80
+ I18n.with_locale(locale || I18n.locale) do
81
+ set_slug(normalize_friendly_id(text))
82
+ end
72
83
  end
73
84
  end
74
85
 
@@ -1,5 +1,3 @@
1
- require "friendly_id/slug"
2
-
3
1
  module FriendlyId
4
2
 
5
3
  =begin
@@ -65,7 +65,7 @@ If you don't pass in a locale argument, FriendlyId::SimpleI18n will just use the
65
65
  current locale:
66
66
 
67
67
  I18n.with_locale(:es) do
68
- post.set_friendly_id("la-guerra-de-las-galaxas")
68
+ post.set_friendly_id("La guerra de las galaxas")
69
69
  end
70
70
  =end
71
71
  module SimpleI18n
data/lib/friendly_id.rb CHANGED
@@ -45,11 +45,12 @@ with numeric ids:
45
45
  module FriendlyId
46
46
 
47
47
  # The current version.
48
- VERSION = "4.0.7"
48
+ VERSION = "4.0.8"
49
49
 
50
50
  @mutex = Mutex.new
51
51
 
52
52
  autoload :History, "friendly_id/history"
53
+ autoload :Slug, "friendly_id/slug"
53
54
  autoload :SimpleI18n, "friendly_id/simple_i18n"
54
55
  autoload :Reserved, "friendly_id/reserved"
55
56
  autoload :Scoped, "friendly_id/scoped"
data/test/core_test.rb CHANGED
@@ -1,13 +1,14 @@
1
1
  require "helper"
2
2
 
3
- class Author < ActiveRecord::Base
3
+ class Book < ActiveRecord::Base
4
4
  extend FriendlyId
5
5
  friendly_id :name
6
6
  end
7
7
 
8
- class Book < ActiveRecord::Base
8
+ class Author < ActiveRecord::Base
9
9
  extend FriendlyId
10
10
  friendly_id :name
11
+ has_many :books
11
12
  end
12
13
 
13
14
  class CoreTest < MiniTest::Unit::TestCase
@@ -32,4 +33,16 @@ class CoreTest < MiniTest::Unit::TestCase
32
33
  test "instances should have a friendly id" do
33
34
  with_instance_of(model_class) {|record| assert record.friendly_id}
34
35
  end
36
+
37
+ test "instances can be marshaled when a relationship is used" do
38
+ transaction do
39
+ author = Author.create :name => 'Philip'
40
+ author.books.create :name => 'my book'
41
+ begin
42
+ assert Marshal.load(Marshal.dump(author))
43
+ rescue TypeError => e
44
+ flunk(e.to_s)
45
+ end
46
+ end
47
+ end
35
48
  end
@@ -11,7 +11,11 @@ end
11
11
  class GlobalizeTest < MiniTest::Unit::TestCase
12
12
  include FriendlyId::Test
13
13
 
14
- test "friendly_id should find slug in current locale if locale is set, otherwise in default locale" do
14
+ def setup
15
+ I18n.locale = :en
16
+ end
17
+
18
+ test "should find slug in current locale if locale is set, otherwise in default locale" do
15
19
  transaction do
16
20
  I18n.default_locale = :en
17
21
  article_en = I18n.with_locale(:en) { TranslatedArticle.create(:title => 'a title') }
@@ -24,6 +28,17 @@ class GlobalizeTest < MiniTest::Unit::TestCase
24
28
  end
25
29
  end
26
30
 
31
+ test "should set friendly id for locale" do
32
+ transaction do
33
+ article = TranslatedArticle.create!(:title => "War and Peace")
34
+ article.set_friendly_id("Guerra y paz", :es)
35
+ article.save!
36
+ article = TranslatedArticle.find('war-and-peace')
37
+ I18n.with_locale(:es) { assert_equal "guerra-y-paz", article.friendly_id }
38
+ I18n.with_locale(:en) { assert_equal "war-and-peace", article.friendly_id }
39
+ end
40
+ end
41
+
27
42
  # https://github.com/svenfuchs/globalize3/blob/master/test/globalize3/dynamic_finders_test.rb#L101
28
43
  # see: https://github.com/svenfuchs/globalize3/issues/100
29
44
  test "record returned by friendly_id should have all translations" do
data/test/helper.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require "rubygems"
2
2
  require "bundler/setup"
3
- require "mocha"
4
3
  require "minitest/unit"
4
+ require "mocha"
5
5
  require "active_record"
6
6
  require 'active_support/core_ext/time/conversions'
7
7
 
@@ -84,4 +84,4 @@ end
84
84
  require "schema"
85
85
  require "shared"
86
86
  FriendlyId::Test::Database.connect
87
- at_exit {ActiveRecord::Base.connection.disconnect!}
87
+ at_exit {ActiveRecord::Base.connection.disconnect!}
data/test/schema.rb CHANGED
@@ -54,17 +54,20 @@ module FriendlyId
54
54
  # This will be used to test globalize translations
55
55
  TranslatedArticle.create_translation_table! :slug => :string, :title => :string
56
56
 
57
+ # This will be used to test relationships
58
+ add_column :books, :author_id, :integer
59
+
57
60
  @done = true
58
61
  end
59
62
 
60
63
  private
61
64
 
62
65
  def slugged_tables
63
- ["journalists", "articles", "novelists", "novels", "manuals", "translated_articles"]
66
+ %w[journalists articles novelists novels manuals translated_articles]
64
67
  end
65
68
 
66
69
  def simple_tables
67
- ["authors", "books", "publishers"]
70
+ %w[authors books publishers]
68
71
  end
69
72
 
70
73
  def tables
data/test/shared.rb CHANGED
@@ -55,7 +55,7 @@ module FriendlyId
55
55
  my_model_class = Class.new(model_class)
56
56
  self.class.const_set("Foo", my_model_class)
57
57
  with_instance_of my_model_class do |record|
58
- record.update_attribute(my_model_class.friendly_id_config.slug_column, nil)
58
+ record.update_attributes my_model_class.friendly_id_config.slug_column => nil
59
59
  record = my_model_class.find(record.id)
60
60
  record.class.validate Proc.new {errors[:name] = "FAIL"}
61
61
  record.save
@@ -8,6 +8,10 @@ class SimpleI18nTest < MiniTest::Unit::TestCase
8
8
  friendly_id :name, :use => :simple_i18n
9
9
  end
10
10
 
11
+ def setup
12
+ I18n.locale = :en
13
+ end
14
+
11
15
  test "friendly_id should return the current locale's slug" do
12
16
  journalist = Journalist.new(:name => "John Doe")
13
17
  journalist.slug_es = "juan-fulano"
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: friendly_id
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.7
4
+ version: 4.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Norman Clarke
9
+ - Philip Arndt
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2012-06-06 00:00:00.000000000 Z
13
+ date: 2012-08-01 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: railties
@@ -48,17 +49,17 @@ dependencies:
48
49
  requirement: !ruby/object:Gem::Requirement
49
50
  none: false
50
51
  requirements:
51
- - - ! '>='
52
+ - - '='
52
53
  - !ruby/object:Gem::Version
53
- version: '0'
54
+ version: 3.2.0
54
55
  type: :development
55
56
  prerelease: false
56
57
  version_requirements: !ruby/object:Gem::Requirement
57
58
  none: false
58
59
  requirements:
59
- - - ! '>='
60
+ - - '='
60
61
  - !ruby/object:Gem::Version
61
- version: '0'
62
+ version: 3.2.0
62
63
  - !ruby/object:Gem::Dependency
63
64
  name: mocha
64
65
  requirement: !ruby/object:Gem::Requirement
@@ -181,6 +182,7 @@ description: ! 'FriendlyId is the "Swiss Army bulldozer" of slugging and permali
181
182
  '
182
183
  email:
183
184
  - norman@njclarke.com
185
+ - parndt@gmail.com
184
186
  executables: []
185
187
  extensions: []
186
188
  extra_rdoc_files: []
@@ -258,12 +260,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
258
260
  - - ! '>='
259
261
  - !ruby/object:Gem::Version
260
262
  version: '0'
263
+ segments:
264
+ - 0
265
+ hash: -4530033734929849472
261
266
  required_rubygems_version: !ruby/object:Gem::Requirement
262
267
  none: false
263
268
  requirements:
264
269
  - - ! '>='
265
270
  - !ruby/object:Gem::Version
266
271
  version: '0'
272
+ segments:
273
+ - 0
274
+ hash: -4530033734929849472
267
275
  requirements: []
268
276
  rubyforge_project: friendly_id
269
277
  rubygems_version: 1.8.24