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.
- data/.gitignore +11 -0
- data/.travis.yml +24 -0
- data/.yardopts +4 -0
- data/Changelog.md +9 -10
- data/README.md +39 -48
- data/Rakefile +56 -58
- data/WhatsNew.md +95 -0
- data/bench.rb +63 -0
- data/friendly_id.gemspec +40 -0
- data/gemfiles/Gemfile.rails-3.0.rb +18 -0
- data/gemfiles/Gemfile.rails-3.0.rb.lock +52 -0
- data/gemfiles/Gemfile.rails-3.1.rb +18 -0
- data/gemfiles/Gemfile.rails-3.1.rb.lock +57 -0
- data/lib/friendly_id.rb +126 -80
- data/lib/friendly_id/active_record_adapter/relation.rb +10 -2
- data/lib/friendly_id/active_record_adapter/slugged_model.rb +3 -9
- data/lib/friendly_id/base.rb +132 -0
- data/lib/friendly_id/configuration.rb +65 -152
- data/lib/friendly_id/finder_methods.rb +20 -0
- data/lib/friendly_id/history.rb +88 -0
- data/lib/friendly_id/migration.rb +18 -0
- data/lib/friendly_id/model.rb +22 -0
- data/lib/friendly_id/object_utils.rb +40 -0
- data/lib/friendly_id/reserved.rb +46 -0
- data/lib/friendly_id/scoped.rb +131 -0
- data/lib/friendly_id/slug.rb +9 -0
- data/lib/friendly_id/slug_sequencer.rb +82 -0
- data/lib/friendly_id/slugged.rb +191 -76
- data/lib/friendly_id/version.rb +2 -2
- data/test/base_test.rb +54 -0
- data/test/configuration_test.rb +27 -0
- data/test/core_test.rb +30 -0
- data/test/databases.yml +19 -0
- data/test/helper.rb +88 -0
- data/test/history_test.rb +55 -0
- data/test/object_utils_test.rb +26 -0
- data/test/reserved_test.rb +26 -0
- data/test/schema.rb +59 -0
- data/test/scoped_test.rb +57 -0
- data/test/shared.rb +118 -0
- data/test/slugged_test.rb +83 -0
- data/test/sti_test.rb +48 -0
- metadata +110 -102
- data/Contributors.md +0 -46
- data/Guide.md +0 -626
- data/extras/README.txt +0 -3
- data/extras/bench.rb +0 -40
- data/extras/extras.rb +0 -38
- data/extras/prof.rb +0 -19
- data/extras/template-gem.rb +0 -26
- data/extras/template-plugin.rb +0 -28
- data/generators/friendly_id/friendly_id_generator.rb +0 -30
- data/generators/friendly_id/templates/create_slugs.rb +0 -18
- data/lib/tasks/friendly_id.rake +0 -19
- data/rails/init.rb +0 -2
- data/test/active_record_adapter/ar_test_helper.rb +0 -149
- data/test/active_record_adapter/basic_slugged_model_test.rb +0 -14
- data/test/active_record_adapter/cached_slug_test.rb +0 -76
- data/test/active_record_adapter/core.rb +0 -138
- data/test/active_record_adapter/custom_normalizer_test.rb +0 -20
- data/test/active_record_adapter/custom_table_name_test.rb +0 -22
- data/test/active_record_adapter/default_scope_test.rb +0 -30
- data/test/active_record_adapter/optimistic_locking_test.rb +0 -18
- data/test/active_record_adapter/scoped_model_test.rb +0 -129
- data/test/active_record_adapter/simple_test.rb +0 -76
- data/test/active_record_adapter/slug_test.rb +0 -34
- data/test/active_record_adapter/slugged.rb +0 -33
- data/test/active_record_adapter/slugged_status_test.rb +0 -28
- data/test/active_record_adapter/sti_test.rb +0 -22
- data/test/active_record_adapter/support/database.jdbcsqlite3.yml +0 -2
- data/test/active_record_adapter/support/database.mysql.yml +0 -4
- data/test/active_record_adapter/support/database.mysql2.yml +0 -4
- data/test/active_record_adapter/support/database.postgres.yml +0 -6
- data/test/active_record_adapter/support/database.sqlite3.yml +0 -2
- data/test/active_record_adapter/support/models.rb +0 -104
- data/test/active_record_adapter/tasks_test.rb +0 -82
- data/test/compatibility/ancestry/Gemfile.lock +0 -34
- data/test/friendly_id_test.rb +0 -96
- data/test/test_helper.rb +0 -13
data/.gitignore
ADDED
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
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
|
-
##
|
9
|
+
## 4.0.0 (NOT_RELEASED_YET)
|
10
10
|
|
11
|
-
|
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.
|
16
|
+
## 3.3.0 (NOT_RELEASED_YET)
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
##
|
25
|
+
## Version 4.x
|
38
26
|
|
39
|
-
|
40
|
-
|
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
|
-
|
52
|
-
gem "friendly_id", "~> 3.3.0"
|
38
|
+
gem "friendly_id", "~> 4.0.0.beta7"
|
53
39
|
|
54
|
-
|
55
|
-
rails generate scaffold user name: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
|
-
|
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://
|
58
|
+
GET http://localhost:3000/users/joe-schmoe
|
59
|
+
|
60
|
+
## Docs
|
69
61
|
|
70
|
-
|
62
|
+
The current docs can be found
|
63
|
+
[here](http://rdoc.info/github/norman/friendly_id/a4128af31d85ee29ad8f/frames).
|
71
64
|
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
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
|
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
|
98
|
-
|
99
|
-
|
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
|
-
|
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-
|
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
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
27
|
-
|
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
|
-
|
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 "
|
49
|
-
task :
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
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
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
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
|