friendly_id 3.3.3.0 → 4.0.0.beta7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/.gitignore +11 -0
  2. data/.travis.yml +24 -0
  3. data/.yardopts +4 -0
  4. data/Changelog.md +9 -10
  5. data/README.md +39 -48
  6. data/Rakefile +56 -58
  7. data/WhatsNew.md +95 -0
  8. data/bench.rb +63 -0
  9. data/friendly_id.gemspec +40 -0
  10. data/gemfiles/Gemfile.rails-3.0.rb +18 -0
  11. data/gemfiles/Gemfile.rails-3.0.rb.lock +52 -0
  12. data/gemfiles/Gemfile.rails-3.1.rb +18 -0
  13. data/gemfiles/Gemfile.rails-3.1.rb.lock +57 -0
  14. data/lib/friendly_id.rb +126 -80
  15. data/lib/friendly_id/active_record_adapter/relation.rb +10 -2
  16. data/lib/friendly_id/active_record_adapter/slugged_model.rb +3 -9
  17. data/lib/friendly_id/base.rb +132 -0
  18. data/lib/friendly_id/configuration.rb +65 -152
  19. data/lib/friendly_id/finder_methods.rb +20 -0
  20. data/lib/friendly_id/history.rb +88 -0
  21. data/lib/friendly_id/migration.rb +18 -0
  22. data/lib/friendly_id/model.rb +22 -0
  23. data/lib/friendly_id/object_utils.rb +40 -0
  24. data/lib/friendly_id/reserved.rb +46 -0
  25. data/lib/friendly_id/scoped.rb +131 -0
  26. data/lib/friendly_id/slug.rb +9 -0
  27. data/lib/friendly_id/slug_sequencer.rb +82 -0
  28. data/lib/friendly_id/slugged.rb +191 -76
  29. data/lib/friendly_id/version.rb +2 -2
  30. data/test/base_test.rb +54 -0
  31. data/test/configuration_test.rb +27 -0
  32. data/test/core_test.rb +30 -0
  33. data/test/databases.yml +19 -0
  34. data/test/helper.rb +88 -0
  35. data/test/history_test.rb +55 -0
  36. data/test/object_utils_test.rb +26 -0
  37. data/test/reserved_test.rb +26 -0
  38. data/test/schema.rb +59 -0
  39. data/test/scoped_test.rb +57 -0
  40. data/test/shared.rb +118 -0
  41. data/test/slugged_test.rb +83 -0
  42. data/test/sti_test.rb +48 -0
  43. metadata +110 -102
  44. data/Contributors.md +0 -46
  45. data/Guide.md +0 -626
  46. data/extras/README.txt +0 -3
  47. data/extras/bench.rb +0 -40
  48. data/extras/extras.rb +0 -38
  49. data/extras/prof.rb +0 -19
  50. data/extras/template-gem.rb +0 -26
  51. data/extras/template-plugin.rb +0 -28
  52. data/generators/friendly_id/friendly_id_generator.rb +0 -30
  53. data/generators/friendly_id/templates/create_slugs.rb +0 -18
  54. data/lib/tasks/friendly_id.rake +0 -19
  55. data/rails/init.rb +0 -2
  56. data/test/active_record_adapter/ar_test_helper.rb +0 -149
  57. data/test/active_record_adapter/basic_slugged_model_test.rb +0 -14
  58. data/test/active_record_adapter/cached_slug_test.rb +0 -76
  59. data/test/active_record_adapter/core.rb +0 -138
  60. data/test/active_record_adapter/custom_normalizer_test.rb +0 -20
  61. data/test/active_record_adapter/custom_table_name_test.rb +0 -22
  62. data/test/active_record_adapter/default_scope_test.rb +0 -30
  63. data/test/active_record_adapter/optimistic_locking_test.rb +0 -18
  64. data/test/active_record_adapter/scoped_model_test.rb +0 -129
  65. data/test/active_record_adapter/simple_test.rb +0 -76
  66. data/test/active_record_adapter/slug_test.rb +0 -34
  67. data/test/active_record_adapter/slugged.rb +0 -33
  68. data/test/active_record_adapter/slugged_status_test.rb +0 -28
  69. data/test/active_record_adapter/sti_test.rb +0 -22
  70. data/test/active_record_adapter/support/database.jdbcsqlite3.yml +0 -2
  71. data/test/active_record_adapter/support/database.mysql.yml +0 -4
  72. data/test/active_record_adapter/support/database.mysql2.yml +0 -4
  73. data/test/active_record_adapter/support/database.postgres.yml +0 -6
  74. data/test/active_record_adapter/support/database.sqlite3.yml +0 -2
  75. data/test/active_record_adapter/support/models.rb +0 -104
  76. data/test/active_record_adapter/tasks_test.rb +0 -82
  77. data/test/compatibility/ancestry/Gemfile.lock +0 -34
  78. data/test/friendly_id_test.rb +0 -96
  79. data/test/test_helper.rb +0 -13
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ Gemfile
2
+ Gemfile.lock
3
+ doc
4
+ docs
5
+ pkg
6
+ .DS_Store
7
+ coverage
8
+ .yardoc
9
+ *.gem
10
+ *.sqlite3
11
+ *.rbc
data/.travis.yml ADDED
@@ -0,0 +1,24 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 1.9.2
4
+ - 1.8.7
5
+ - rbx-2.0
6
+ # Temporarily not testing JRuby in CI because ActiveRecord JDBC does not
7
+ # support 3.1 well yet. Rest assured I'm testing this and want to target
8
+ # JRuby, I just don't want to see broken build messages all the time when I
9
+ # already know what the probelem is.
10
+ # - jruby
11
+
12
+ branches:
13
+ only:
14
+ - master
15
+ env:
16
+ - DB=postgres
17
+ - DB=mysql
18
+ - DB=sqlite3
19
+
20
+ gemfile:
21
+ - gemfiles/Gemfile.rails-3.0.rb
22
+ - gemfiles/Gemfile.rails-3.1.rb
23
+
24
+ script: "bundle exec rake db:reset db:up test"
data/.yardopts ADDED
@@ -0,0 +1,4 @@
1
+ --files=*.md
2
+ --protected
3
+ --list-undoc
4
+ --exclude lib/friendly_id/migration
data/Changelog.md CHANGED
@@ -6,19 +6,18 @@ suggestions, ideas and improvements to FriendlyId.
6
6
  * Table of Contents
7
7
  {:toc}
8
8
 
9
- ## 3.1.3 (2012-04-28)
9
+ ## 4.0.0 (NOT_RELEASED_YET)
10
10
 
11
- * Fix for sequenced scoped slugs ([Louise Crow](https://github.com/crowbot))
11
+ This is a complete rewrite of FriendlyId, and introduces a smaller, faster and
12
+ less ambitious codebase. The primary change is the relegation of external slugs
13
+ to an optional addon, and the adoption of what were formerly "cached slugs"
14
+ as the primary way of handling slugging.
12
15
 
13
- ## 3.1.2 (2012-01-24)
16
+ ## 3.3.0 (NOT_RELEASED_YET)
14
17
 
15
- * Fix for 3.2 support ([Philip Arndt](https://github.com/parndt))
16
-
17
- ## 3.1.1 (2011-12-12)
18
-
19
- * Fix for "can't modify frozen hash" on 3.1 ([Theo Cushion](https://github.com/theozaurus))
20
-
21
- ## 3.3.0 (2011-08-31)
18
+ This is a compatiblity branch and will be maintained for apps that can't
19
+ upgrade to 4.0. No new features are planned, only bugfixes. If you're creating
20
+ a new app, please use 4.x.
22
21
 
23
22
  * Support for Active Record 2.3 dropped
24
23
  * Convert blank slugs to nil automatically ([Gabe da Silveira ](https://github.com/dasil003))
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # FriendlyId
2
2
 
3
+ [![Build Status](http://travis-ci.org/norman/friendly_id.png)](http://travis-ci.org/norman/friendly_id)
4
+
3
5
  FriendlyId is the "Swiss Army bulldozer" of slugging and permalink plugins for
4
- Ruby on Rails. It allows you to create pretty URL's and work with
5
- human-friendly strings as if they were numeric ids for Active Record models.
6
+ Ruby on Rails. It allows you to create pretty URL's and work with human-friendly
7
+ strings as if they were numeric ids for Active Record models.
6
8
 
7
9
  Using FriendlyId, it's easy to make your application use URL's like:
8
10
 
@@ -12,33 +14,18 @@ instead of:
12
14
 
13
15
  http://example.com/states/4323454
14
16
 
17
+
15
18
  ## FriendlyId Features
16
19
 
17
20
  FriendlyId offers many advanced features, including: slug history and
18
- versioning, scoped slugs, reserved words, custom slug generators, and
19
- excellent Unicode support. For complete information on using FriendlyId,
20
- please see the [FriendlyId Guide](https://github.com/norman/friendly_id/blob/3.x/Guide.md)
21
-
22
- ## Compatibility
23
-
24
- FriendlyId 3.3.0 is compatible with Active Record 3.0, 3.1 and 3.2.
25
-
26
- If you are still on Rails 2.3, please use FriendlyId 3.2.x.
27
-
28
- ## Roadmap
29
-
30
- FriendlyId 3.3 is now in **long term maintenance mode.** It will continue to be
31
- supported and maintained indefinitely, but no new features will be added to it.
21
+ versioning, scoped slugs, reserved words, and custom slug generators.
32
22
 
33
- [FriendlyId 4.0](https://github.com/norman/friendly_id/tree/4.0.0) is a
34
- ground-up rewrite of FriendlyId, and is the project's future, and will be
35
- released by September, 2011.
23
+ FriendlyId is compatible with Active Record **3.0** and **3.1**.
36
24
 
37
- ## Docs, Info and Support
25
+ ## Version 4.x
38
26
 
39
- * [FriendlyId Guide](https://github.com/norman/friendly_id/blob/3.x/Guide.md)
40
- * [Source Code](http://github.com/norman/friendly_id/)
41
- * [Issue Tracker](http://github.com/norman/friendly_id/issues)
27
+ FriendlyId 4.x introduces many changes incompatible with 3.x. If you're upgrading,
28
+ please read the docs to see what's new.
42
29
 
43
30
  ## Rails Quickstart
44
31
 
@@ -48,45 +35,49 @@ released by September, 2011.
48
35
 
49
36
  cd my_app
50
37
 
51
- # add to Gemfile
52
- gem "friendly_id", "~> 3.3.0"
38
+ gem "friendly_id", "~> 4.0.0.beta7"
53
39
 
54
- rails generate friendly_id
55
- rails generate scaffold user name:string cached_slug:string
40
+
41
+ rails generate scaffold user name:string slug:string
42
+
43
+ # edit db/migrate/*_create_users.rb
44
+ add_index :users, :slug, :unique => true
56
45
 
57
46
  rake db:migrate
58
47
 
59
48
  # edit app/models/user.rb
60
49
  class User < ActiveRecord::Base
61
- has_friendly_id :name, :use_slug => true
50
+ extend FriendlyId
51
+ friendly_id :name, :use => :slugged
62
52
  end
63
53
 
64
54
  User.create! :name => "Joe Schmoe"
65
55
 
66
56
  rails server
67
57
 
68
- GET http://0.0.0.0:3000/users/joe-schmoe
58
+ GET http://localhost:3000/users/joe-schmoe
59
+
60
+ ## Docs
69
61
 
70
- ## Sequel and DataMapper, too
62
+ The current docs can be found
63
+ [here](http://rdoc.info/github/norman/friendly_id/a4128af31d85ee29ad8f/frames).
71
64
 
72
- [Alex Coles](http://github.com/myabc) maintains an implemntation of
73
- [FriendlyId for DataMapper](http://github.com/myabc/friendly_id_datamapper) that supports almost
74
- all the features of the Active Record version.
65
+ ## Benchmarks
66
+
67
+ The latest benchmarks for FriendlyId are maintained
68
+ [here](https://gist.github.com/1129745).
75
69
 
76
- Norman Clarke maintains an implementation of
77
- [FriendlyId forSequel](http://github.com/norman/friendly_id_sequel) with some of the features
78
- of the Active Record version.
79
70
 
80
71
  ## Bugs
81
72
 
82
- Please report them on the [Github issue tracker](http://github.com/norman/friendly_id/issues)
83
- for this project.
73
+ Please report them on the [Github issue
74
+ tracker](http://github.com/norman/friendly_id/issues) for this project.
84
75
 
85
76
  If you have a bug to report, please include the following information:
86
77
 
87
78
  * **Version information for FriendlyId, Rails and Ruby.**
88
79
  * Stack trace and error message.
89
- * Any snippets of relevant model, view or controller code that shows how your
80
+ * Any snippets of relevant model, view or controller code that shows how you
90
81
  are using FriendlyId.
91
82
 
92
83
  If you are able to, it helps even more if you can fork FriendlyId on Github,
@@ -94,14 +85,14 @@ and add a test that reproduces the error you are experiencing.
94
85
 
95
86
  ## Credits
96
87
 
97
- FriendlyId was created by Norman Clarke, Adrian Mugnolo, and Emilio Tagua.
98
-
99
- If you like FriendlyId, please recommend us on Working With Rails:
100
-
101
- * [http://bit.ly/recommend-norman](http://bit.ly/recommend-norman)
102
- * [http://bit.ly/recommend-emilio](http://bit.ly/recommend-emilio)
103
- * [http://bit.ly/recommend-adrian](http://bit.ly/recommend-adrian)
88
+ FriendlyId was originally created by Norman Clarke and Adrian Mugnolo, with
89
+ significant help early in its life by Emilio Tagua. I'm deeply gratful for the
90
+ generous contributions over the years from [many
91
+ volunteers](https://github.com/norman/friendly_id/contributors).
104
92
 
105
- Thanks!
93
+ Lastly, FriendlyId uses [Travis](http://travis-ci.org/) for continuous
94
+ integration. It's an excellent, free service created by a whole bunch of [good
95
+ people](https://github.com/travis-ci) - if you're not already using it, you
96
+ should be!
106
97
 
107
- Copyright (c) 2008-2010, released under the MIT license.
98
+ Copyright (c) 2008-2011 Norman Clarke, released under the MIT license.
data/Rakefile CHANGED
@@ -1,79 +1,77 @@
1
1
  require "rubygems"
2
- require "rake"
3
2
  require "rake/testtask"
4
- require "rubygems/package_task"
5
- require "rake/clean"
6
- require "bundler/setup"
7
3
 
8
4
  task :default => :test
9
5
 
10
- CLEAN << "pkg" << "doc" << "coverage" << ".yardoc"
11
-
12
- gemspec = File.expand_path("../friendly_id.gemspec", __FILE__)
13
- if File.exists? gemspec
14
- Gem::PackageTask.new(eval(File.read("friendly_id.gemspec"))) { |pkg| }
6
+ Rake::TestTask.new do |t|
7
+ t.test_files = FileList['test/*_test.rb']
8
+ t.verbose = true
15
9
  end
16
10
 
17
- begin
18
- require "yard"
19
- YARD::Rake::YardocTask.new do |t|
20
- t.options = ["--output-dir=doc"]
21
- t.options << "--files" << ["Guide.md", "Contributors.md", "Changelog.md"].join(",")
22
- end
23
- rescue LoadError
11
+ task :clean do
12
+ %x{rm -rf *.gem doc pkg coverage}
13
+ %x{rm -f `find . -name '*.rbc'`}
24
14
  end
25
15
 
26
- begin
27
- require "rcov/rcovtask"
28
- Rcov::RcovTask.new do |r|
29
- r.test_files = FileList["test/**/*_test.rb"]
30
- r.verbose = true
31
- r.rcov_opts << "--exclude gems/*"
32
- end
33
- rescue LoadError
16
+ task :gem do
17
+ %x{gem build friendly_id.gemspec}
34
18
  end
35
19
 
20
+ task :yard do
21
+ puts %x{bundle exec yard}
22
+ end
36
23
 
37
- Rake::TestTask.new(:test) { |t| t.pattern = "test/**/*_test.rb" }
24
+ task :bench do
25
+ require File.expand_path("../bench", __FILE__)
26
+ end
38
27
 
39
28
  namespace :test do
40
- task :rails do
41
- rm_rf "fid"
42
- sh "rails --template extras/template-gem.rb fid"
43
- sh "cd fid; rake test"
44
- end
45
- Rake::TestTask.new(:friendly_id) { |t| t.pattern = "test/*_test.rb" }
46
- Rake::TestTask.new(:ar) { |t| t.pattern = "test/active_record_adapter/*_test.rb" }
47
29
 
48
- desc "Test against lots of versions"
49
- task :pre_release do
50
- ["ree-1.8.7-2010.02", "ruby-1.9.2-p136"].each do |ruby|
51
- ["sqlite3", "mysql", "postgres"].each do |driver|
52
- [2, 3].each do |ar_version|
53
- command = "rake-#{ruby} test AR=#{ar_version} DB=#{driver}"
54
- puts command
55
- puts `#{command}`
56
- end
57
- end
30
+ desc "Run each test class in a separate process"
31
+ task :isolated do
32
+ dir = File.expand_path("../test", __FILE__)
33
+ Dir["#{dir}/*_test.rb"].each do |test|
34
+ puts "Running #{test}:"
35
+ puts %x{ruby #{test}}
58
36
  end
59
37
  end
38
+ end
60
39
 
61
- namespace :rails do
62
- task :plugin do
63
- rm_rf "fid"
64
- sh "rails --template extras/template-plugin.rb fid"
65
- sh "cd fid; rake test"
66
- end
40
+ namespace :db do
41
+
42
+ desc "Create the database"
43
+ task :create do
44
+ require File.expand_path("../test/helper", __FILE__)
45
+ driver = FriendlyId::Test::Database.driver
46
+ config = FriendlyId::Test::Database.config[driver]
47
+ commands = {
48
+ "mysql" => "mysql -e 'create database #{config["database"]};' >/dev/null",
49
+ "postgres" => "psql -c 'create database #{config['database']};' -U #{config['username']} >/dev/null"
50
+ }
51
+ %x{#{commands[driver] || true}}
52
+ end
53
+
54
+ desc "Create the database"
55
+ task :drop do
56
+ require File.expand_path("../test/helper", __FILE__)
57
+ driver = FriendlyId::Test::Database.driver
58
+ config = FriendlyId::Test::Database.config[driver]
59
+ commands = {
60
+ "mysql" => "mysql -e 'drop database #{config["database"]};' >/dev/null",
61
+ "postgres" => "psql -c 'drop database #{config['database']};' -U #{config['username']} >/dev/null"
62
+ }
63
+ %x{#{commands[driver] || true}}
67
64
  end
68
- end
69
65
 
70
- task :pushdocs do
71
- branch = `git branch | grep "*"`.chomp.gsub("* ", "")
72
- sh "git stash"
73
- sh "git checkout gh-pages"
74
- sh "cp -rp doc/* ."
75
- sh 'git commit -a -m "Regenerated docs"'
76
- sh "git push origin gh-pages"
77
- sh "git checkout #{branch}"
78
- sh "git stash apply"
66
+ desc "Set up the database schema"
67
+ task :up do
68
+ require File.expand_path("../test/helper", __FILE__)
69
+ FriendlyId::Test::Schema.up
70
+ end
71
+
72
+ desc "Drop and recreate the database schema"
73
+ task :reset => [:drop, :create]
74
+
79
75
  end
76
+
77
+ task :doc => :yard
data/WhatsNew.md ADDED
@@ -0,0 +1,95 @@
1
+ # What's New in FriendlyId 4?
2
+
3
+ ## Back to basics
4
+
5
+ FriendlyId is mostly a different codebase from FriendlyId 3. However, this isn't
6
+ the "big rewrite," it's the "small rewrite:"
7
+
8
+ Adding new features with each release is not sustainable. This release *removes*
9
+ features, but makes it possible to add them back as addons. We can also remove
10
+ some complexity by relying on the better default functionality provided by newer
11
+ versions of Active Support and Active Record.
12
+
13
+ Here's what's changed:
14
+
15
+ ## New configuration and setup
16
+
17
+ FriendlyId is no longer added to Active Record by default, you must explicitly
18
+ add it to each model you want to use it in. The method and options have also
19
+ changed:
20
+
21
+ # FriendlyId 3
22
+ class Post < ActiveRecord::Base
23
+ has_friendly_id :title, :use_slugs => true
24
+ end
25
+
26
+ # FriendlyId 4
27
+ class Post < ActiveRecord::Base
28
+ extend FriendlyId
29
+ friendly_id :title, :use => :slugged
30
+ end
31
+
32
+ It also adds a new "defaults" method for configuring all models:
33
+
34
+ FriendlyId.defaults do |config|
35
+ config.use :slugged, :reserved
36
+ config.base = :name
37
+ end
38
+
39
+ ## Active Record 3+ only
40
+
41
+ For 2.3 support, you can use FriendlyId 3.x, which will continue to be maintained
42
+ until people don't want it any more.
43
+
44
+ ## In-table slugs
45
+
46
+ FriendlyId no longer creates a separate slugs table - it just stores the
47
+ generated slug value in the model table, which is simpler, faster and what most
48
+ want by default. Keeping slug history in a separate table is an
49
+ {FriendlyId::Slugged optional add-on} for FriendlyId 4.
50
+
51
+ ## No more multiple finds
52
+
53
+ Person.find "joe-schmoe" # Supported
54
+ Person.find ["joe-schmoe", "john-doe"] # No longer supported
55
+
56
+ If you want find by more than one friendly id, build your own query:
57
+
58
+ Person.where(:slug => ["joe-schmoe", "john-doe"])
59
+
60
+ This lets us do *far* less monkeypatching in Active Record. How much less?
61
+ FriendlyId overrides the base find with a mere 2 lines of code, and otherwise
62
+ changes nothing else. This means more stability and less breakage between Rails
63
+ updates.
64
+
65
+ ## No more finder status
66
+
67
+ FriendlyId 3 offered finder statuses to help you determine when an outdated
68
+ or non-friendly id was used to find the record, so that you could decide whether
69
+ to permanently redirect to the canonical URL. However, there's a simpler way to
70
+ do that, so this feature has been removed:
71
+
72
+ if request.path != person_path(@person)
73
+ return redirect_to @person, :status => :moved_permanently
74
+ end
75
+
76
+ ## Bye-bye Babosa
77
+
78
+ [Babosa](http://github.com/norman/babosa) is FriendlyId 3's slugging library.
79
+
80
+ FriendlyId 4 doesn't use it by default because the most important pieces of it
81
+ were already accepted into Active Support 3.
82
+
83
+ However, Babosa is still useful, for example, for idiomatically transliterating
84
+ Cyrillic ([or other
85
+ language](https://github.com/norman/babosa/tree/master/lib/babosa/transliterator))
86
+ strings to ASCII. It's very easy to include - just override
87
+ `#normalize_friendly_id` in your model:
88
+
89
+ class MyModel < ActiveRecord::Base
90
+ ...
91
+
92
+ def normalize_friendly_id(text)
93
+ text.to_slug.normalize! :transliterate => :russian
94
+ end
95
+ end