friendly_id_globalize3 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog.md +354 -0
- data/Contributors.md +43 -0
- data/Guide.md +686 -0
- data/MIT-LICENSE +19 -0
- data/README.md +99 -0
- data/Rakefile +75 -0
- data/extras/README.txt +3 -0
- data/extras/bench.rb +40 -0
- data/extras/extras.rb +38 -0
- data/extras/prof.rb +19 -0
- data/extras/template-gem.rb +26 -0
- data/extras/template-plugin.rb +28 -0
- data/generators/friendly_id/friendly_id_generator.rb +30 -0
- data/generators/friendly_id/templates/create_slugs.rb +18 -0
- data/lib/friendly_id.rb +93 -0
- data/lib/friendly_id/active_record.rb +74 -0
- data/lib/friendly_id/active_record_adapter/configuration.rb +68 -0
- data/lib/friendly_id/active_record_adapter/finders.rb +148 -0
- data/lib/friendly_id/active_record_adapter/relation.rb +165 -0
- data/lib/friendly_id/active_record_adapter/simple_model.rb +63 -0
- data/lib/friendly_id/active_record_adapter/slug.rb +77 -0
- data/lib/friendly_id/active_record_adapter/slugged_model.rb +122 -0
- data/lib/friendly_id/active_record_adapter/tasks.rb +72 -0
- data/lib/friendly_id/configuration.rb +178 -0
- data/lib/friendly_id/datamapper.rb +5 -0
- data/lib/friendly_id/railtie.rb +22 -0
- data/lib/friendly_id/sequel.rb +5 -0
- data/lib/friendly_id/slug_string.rb +25 -0
- data/lib/friendly_id/slugged.rb +105 -0
- data/lib/friendly_id/status.rb +35 -0
- data/lib/friendly_id/test.rb +350 -0
- data/lib/friendly_id/version.rb +9 -0
- data/lib/generators/friendly_id_generator.rb +25 -0
- data/lib/tasks/friendly_id.rake +19 -0
- data/rails/init.rb +2 -0
- data/test/active_record_adapter/ar_test_helper.rb +150 -0
- data/test/active_record_adapter/basic_slugged_model_test.rb +14 -0
- data/test/active_record_adapter/cached_slug_test.rb +76 -0
- data/test/active_record_adapter/core.rb +138 -0
- data/test/active_record_adapter/custom_normalizer_test.rb +20 -0
- data/test/active_record_adapter/custom_table_name_test.rb +22 -0
- data/test/active_record_adapter/default_scope_test.rb +30 -0
- data/test/active_record_adapter/optimistic_locking_test.rb +18 -0
- data/test/active_record_adapter/scoped_model_test.rb +119 -0
- data/test/active_record_adapter/simple_test.rb +76 -0
- data/test/active_record_adapter/slug_test.rb +34 -0
- data/test/active_record_adapter/slugged.rb +33 -0
- data/test/active_record_adapter/slugged_status_test.rb +28 -0
- data/test/active_record_adapter/sti_test.rb +22 -0
- data/test/active_record_adapter/support/database.jdbcsqlite3.yml +2 -0
- data/test/active_record_adapter/support/database.mysql.yml +4 -0
- data/test/active_record_adapter/support/database.postgres.yml +6 -0
- data/test/active_record_adapter/support/database.sqlite3.yml +2 -0
- data/test/active_record_adapter/support/models.rb +104 -0
- data/test/active_record_adapter/tasks_test.rb +82 -0
- data/test/friendly_id_test.rb +96 -0
- data/test/test_helper.rb +13 -0
- metadata +193 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2008-2010 Norman Clarke, Adrian Mugnolo and Emilio Tagua.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
# FriendlyId
|
2
|
+
|
3
|
+
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
|
+
|
7
|
+
Using FriendlyId, it's easy to make your application use URL's like:
|
8
|
+
|
9
|
+
http://example.com/states/washington
|
10
|
+
|
11
|
+
instead of:
|
12
|
+
|
13
|
+
http://example.com/states/4323454
|
14
|
+
|
15
|
+
## FriendlyId Features
|
16
|
+
|
17
|
+
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](http://norman.github.com/friendly_id/file.Guide.html).
|
21
|
+
|
22
|
+
FriendlyId is compatible with Active Record **2.3.x** and **3.0**.
|
23
|
+
|
24
|
+
## Docs, Info and Support
|
25
|
+
|
26
|
+
* [FriendlyId Guide](http://norman.github.com/friendly_id/file.Guide.html)
|
27
|
+
* [API Docs](http://norman.github.com/friendly_id)
|
28
|
+
* [Google Group](http://groups.google.com/group/friendly_id)
|
29
|
+
* [Source Code](http://github.com/norman/friendly_id/)
|
30
|
+
* [Issue Tracker](http://github.com/norman/friendly_id/issues)
|
31
|
+
|
32
|
+
## Rails Quickstart
|
33
|
+
|
34
|
+
Note that the example below uses Rails 3. But don't worry: FriendlyId will
|
35
|
+
continue to support 2.3.x until Rails 3.1 is released.
|
36
|
+
|
37
|
+
gem install friendly_id
|
38
|
+
|
39
|
+
rails new my_app
|
40
|
+
|
41
|
+
cd my_app
|
42
|
+
|
43
|
+
# add to Gemfile
|
44
|
+
gem "friendly_id", "~> 3.2"
|
45
|
+
|
46
|
+
rails generate friendly_id
|
47
|
+
rails generate scaffold user name:string cached_slug:string
|
48
|
+
|
49
|
+
rake db:migrate
|
50
|
+
|
51
|
+
# edit app/models/user.rb
|
52
|
+
class User < ActiveRecord::Base
|
53
|
+
has_friendly_id :name, :use_slug => true
|
54
|
+
end
|
55
|
+
|
56
|
+
User.create! :name => "Joe Schmoe"
|
57
|
+
|
58
|
+
rails server
|
59
|
+
|
60
|
+
GET http://0.0.0.0:3000/users/joe-schmoe
|
61
|
+
|
62
|
+
## Sequel and DataMapper, too
|
63
|
+
|
64
|
+
[Alex Coles](http://github.com/myabc) maintains an implemntation of
|
65
|
+
[FriendlyId for DataMapper](http://github.com/myabc/friendly_id_datamapper) that supports almost
|
66
|
+
all the features of the Active Record version.
|
67
|
+
|
68
|
+
Norman Clarke maintains an implementation of
|
69
|
+
[FriendlyId forSequel](http://github.com/norman/friendly_id_sequel) with some of the features
|
70
|
+
of the Active Record version.
|
71
|
+
|
72
|
+
## Bugs
|
73
|
+
|
74
|
+
Please report them on the [Github issue tracker](http://github.com/norman/friendly_id/issues)
|
75
|
+
for this project.
|
76
|
+
|
77
|
+
If you have a bug to report, please include the following information:
|
78
|
+
|
79
|
+
* **Version information for FriendlyId, Rails and Ruby.**
|
80
|
+
* Stack trace and error message.
|
81
|
+
* Any snippets of relevant model, view or controller code that shows how your
|
82
|
+
are using FriendlyId.
|
83
|
+
|
84
|
+
If you are able to, it helps even more if you can fork FriendlyId on Github,
|
85
|
+
and add a test that reproduces the error you are experiencing.
|
86
|
+
|
87
|
+
## Credits
|
88
|
+
|
89
|
+
FriendlyId was created by Norman Clarke, Adrian Mugnolo, and Emilio Tagua.
|
90
|
+
|
91
|
+
If you like FriendlyId, please recommend us on Working With Rails:
|
92
|
+
|
93
|
+
* [http://bit.ly/recommend-norman](http://bit.ly/recommend-norman)
|
94
|
+
* [http://bit.ly/recommend-emilio](http://bit.ly/recommend-emilio)
|
95
|
+
* [http://bit.ly/recommend-adrian](http://bit.ly/recommend-adrian)
|
96
|
+
|
97
|
+
Thanks!
|
98
|
+
|
99
|
+
Copyright (c) 2008-2010, released under the MIT license.
|
data/Rakefile
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
require "rake"
|
4
|
+
require "rake/testtask"
|
5
|
+
require "rake/gempackagetask"
|
6
|
+
require "rake/clean"
|
7
|
+
|
8
|
+
task :default => :test
|
9
|
+
|
10
|
+
CLEAN << "pkg" << "doc" << "coverage" << ".yardoc"
|
11
|
+
Rake::GemPackageTask.new(eval(File.read("friendly_id.gemspec"))) { |pkg| }
|
12
|
+
|
13
|
+
begin
|
14
|
+
require "yard"
|
15
|
+
YARD::Rake::YardocTask.new do |t|
|
16
|
+
t.options = ["--output-dir=doc"]
|
17
|
+
t.options << "--files" << ["Guide.md", "Contributors.md", "Changelog.md"].join(",")
|
18
|
+
end
|
19
|
+
rescue LoadError
|
20
|
+
end
|
21
|
+
|
22
|
+
begin
|
23
|
+
require "rcov/rcovtask"
|
24
|
+
Rcov::RcovTask.new do |r|
|
25
|
+
r.test_files = FileList["test/**/*_test.rb"]
|
26
|
+
r.verbose = true
|
27
|
+
r.rcov_opts << "--exclude gems/*"
|
28
|
+
end
|
29
|
+
rescue LoadError
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
Rake::TestTask.new(:test) { |t| t.pattern = "test/**/*_test.rb" }
|
34
|
+
|
35
|
+
namespace :test do
|
36
|
+
task :rails do
|
37
|
+
rm_rf "fid"
|
38
|
+
sh "rails --template extras/template-gem.rb fid"
|
39
|
+
sh "cd fid; rake test"
|
40
|
+
end
|
41
|
+
Rake::TestTask.new(:friendly_id) { |t| t.pattern = "test/*_test.rb" }
|
42
|
+
Rake::TestTask.new(:ar) { |t| t.pattern = "test/active_record_adapter/*_test.rb" }
|
43
|
+
|
44
|
+
desc "Test against lots of versions"
|
45
|
+
task :pre_release do
|
46
|
+
["ree-1.8.7-2010.02", "ruby-1.9.2-p0"].each do |ruby|
|
47
|
+
["sqlite3", "mysql", "postgres"].each do |driver|
|
48
|
+
[2, 3].each do |ar_version|
|
49
|
+
command = "rake-#{ruby} test AR=#{ar_version} DB=#{driver}"
|
50
|
+
puts command
|
51
|
+
puts `#{command}`
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
namespace :rails do
|
58
|
+
task :plugin do
|
59
|
+
rm_rf "fid"
|
60
|
+
sh "rails --template extras/template-plugin.rb fid"
|
61
|
+
sh "cd fid; rake test"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
task :pushdocs do
|
67
|
+
branch = `git branch | grep "*"`.chomp.gsub("* ", "")
|
68
|
+
sh "git stash"
|
69
|
+
sh "git checkout gh-pages"
|
70
|
+
sh "cp -rp doc/* ."
|
71
|
+
sh 'git commit -a -m "Regenerated docs"'
|
72
|
+
sh "git push origin gh-pages"
|
73
|
+
sh "git checkout #{branch}"
|
74
|
+
sh "git stash apply"
|
75
|
+
end
|
data/extras/README.txt
ADDED
data/extras/bench.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
$:.unshift File.expand_path("../lib", File.dirname(__FILE__))
|
2
|
+
$:.unshift File.expand_path(File.dirname(__FILE__))
|
3
|
+
$:.uniq!
|
4
|
+
|
5
|
+
require "extras"
|
6
|
+
require 'rbench'
|
7
|
+
FACTOR = 10
|
8
|
+
|
9
|
+
RBench.run(TIMES) do
|
10
|
+
|
11
|
+
column :times
|
12
|
+
column :default
|
13
|
+
column :no_slug
|
14
|
+
column :slug
|
15
|
+
column :cached_slug
|
16
|
+
|
17
|
+
report 'find model by id', (TIMES * FACTOR).ceil do
|
18
|
+
default { User.find(get_id) }
|
19
|
+
no_slug { User.find(USERS.rand) }
|
20
|
+
slug { Post.find(POSTS.rand) }
|
21
|
+
cached_slug { District.find(DISTRICTS.rand) }
|
22
|
+
end
|
23
|
+
|
24
|
+
report 'find model using array of ids', (TIMES * FACTOR).ceil do
|
25
|
+
default { User.find(get_id(2)) }
|
26
|
+
no_slug { User.find(USERS.rand(2)) }
|
27
|
+
slug { Post.find(POSTS.rand(2)) }
|
28
|
+
cached_slug { District.find(DISTRICTS.rand(2)) }
|
29
|
+
end
|
30
|
+
|
31
|
+
report 'find model using id, then to_param', (TIMES * FACTOR).ceil do
|
32
|
+
default { User.find(get_id).to_param }
|
33
|
+
no_slug { User.find(USERS.rand).to_param }
|
34
|
+
slug { Post.find(POSTS.rand).to_param }
|
35
|
+
cached_slug { District.find(DISTRICTS.rand).to_param }
|
36
|
+
end
|
37
|
+
|
38
|
+
summary 'Total'
|
39
|
+
|
40
|
+
end
|
data/extras/extras.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby -KU
|
2
|
+
require File.dirname(__FILE__) + '/../test/test_helper'
|
3
|
+
require File.dirname(__FILE__) + '/../test/active_record_adapter/ar_test_helper'
|
4
|
+
require 'ffaker'
|
5
|
+
|
6
|
+
TIMES = (ENV['N'] || 100).to_i
|
7
|
+
POSTS = []
|
8
|
+
DISTRICTS = []
|
9
|
+
USERS = []
|
10
|
+
|
11
|
+
User.delete_all
|
12
|
+
Post.delete_all
|
13
|
+
District.delete_all
|
14
|
+
Slug.delete_all
|
15
|
+
|
16
|
+
100.times do
|
17
|
+
name = Faker::Name.name
|
18
|
+
USERS << (User.create! :name => name).friendly_id
|
19
|
+
POSTS << (Post.create! :name => name).friendly_id
|
20
|
+
DISTRICTS << (District.create! :name => name).friendly_id
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_id(returns = 1)
|
24
|
+
(1..100).to_a.rand(returns)
|
25
|
+
end
|
26
|
+
|
27
|
+
class Array
|
28
|
+
def rand(returns = 1)
|
29
|
+
@return = []
|
30
|
+
returns.times do
|
31
|
+
until @return.length == returns do
|
32
|
+
val = self[Kernel.rand(length)]
|
33
|
+
@return << val unless @return.include? val
|
34
|
+
end
|
35
|
+
end
|
36
|
+
return returns == 1 ? @return.first : @return
|
37
|
+
end
|
38
|
+
end
|
data/extras/prof.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
$:.unshift File.expand_path("../lib", File.dirname(__FILE__))
|
2
|
+
$:.unshift File.expand_path(File.dirname(__FILE__))
|
3
|
+
$:.uniq!
|
4
|
+
|
5
|
+
require "extras"
|
6
|
+
require 'ruby-prof'
|
7
|
+
|
8
|
+
# RubyProf.measure_mode = RubyProf::MEMORY
|
9
|
+
GC.disable
|
10
|
+
RubyProf.start
|
11
|
+
100.times do
|
12
|
+
Post.find(slug = POSTS.rand)
|
13
|
+
end
|
14
|
+
result = RubyProf.stop
|
15
|
+
GC.enable
|
16
|
+
# printer = RubyProf::CallTreePrinter.new(result)
|
17
|
+
printer = RubyProf::GraphPrinter.new(result)
|
18
|
+
version = ActiveRecord::VERSION::STRING.gsub(".", "")
|
19
|
+
printer.print(File.new("prof#{version}.txt", "w"))
|
@@ -0,0 +1,26 @@
|
|
1
|
+
run "rm public/index.html"
|
2
|
+
gem "friendly_id"
|
3
|
+
gem "haml"
|
4
|
+
gem "will_paginate"
|
5
|
+
run "haml --rails ."
|
6
|
+
generate "friendly_id"
|
7
|
+
generate :haml_scaffold, "post title:string"
|
8
|
+
route "map.root :controller => 'posts', :action => 'index'"
|
9
|
+
rake "db:migrate"
|
10
|
+
rake "db:fixtures:load"
|
11
|
+
file 'app/models/post.rb',
|
12
|
+
%q{class Post < ActiveRecord::Base
|
13
|
+
has_friendly_id :title, :use_slug => true
|
14
|
+
end}
|
15
|
+
file 'test/fixtures/slugs.yml',
|
16
|
+
%q{
|
17
|
+
one:
|
18
|
+
name: mystring
|
19
|
+
sequence: 1
|
20
|
+
sluggable: one (Post)
|
21
|
+
|
22
|
+
two:
|
23
|
+
name: mystring
|
24
|
+
sequence: 1
|
25
|
+
sluggable: two (Post)
|
26
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
run "rm public/index.html"
|
2
|
+
inside 'vendor/plugins' do
|
3
|
+
run "git clone ../../../ friendly_id"
|
4
|
+
end
|
5
|
+
gem "haml"
|
6
|
+
gem "will_paginate"
|
7
|
+
run "haml --rails ."
|
8
|
+
generate "friendly_id"
|
9
|
+
generate :haml_scaffold, "post title:string"
|
10
|
+
route "map.root :controller => 'posts', :action => 'index'"
|
11
|
+
rake "db:migrate"
|
12
|
+
rake "db:fixtures:load"
|
13
|
+
file 'app/models/post.rb',
|
14
|
+
%q{class Post < ActiveRecord::Base
|
15
|
+
has_friendly_id :title, :use_slug => true
|
16
|
+
end}
|
17
|
+
file 'test/fixtures/slugs.yml',
|
18
|
+
%q{
|
19
|
+
one:
|
20
|
+
name: mystring
|
21
|
+
sequence: 1
|
22
|
+
sluggable: one (Post)
|
23
|
+
|
24
|
+
two:
|
25
|
+
name: mystring
|
26
|
+
sequence: 2
|
27
|
+
sluggable: two (Post)
|
28
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class FriendlyIdGenerator < Rails::Generator::Base
|
2
|
+
|
3
|
+
RAKE_TASKS = File.join("..", "..", "..", "lib", "tasks", "friendly_id.rake")
|
4
|
+
|
5
|
+
def manifest
|
6
|
+
record do |m|
|
7
|
+
unless options[:skip_migration]
|
8
|
+
m.migration_template('create_slugs.rb', 'db/migrate', :migration_file_name => 'create_slugs')
|
9
|
+
end
|
10
|
+
unless options[:skip_tasks]
|
11
|
+
m.directory "lib/tasks"
|
12
|
+
m.file RAKE_TASKS, "lib/tasks/friendly_id.rake"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def add_options!(opt)
|
20
|
+
opt.separator ''
|
21
|
+
opt.separator 'Options:'
|
22
|
+
opt.on("--skip-migration", "Don't generate a migration for the slugs table") do |value|
|
23
|
+
options[:skip_migration] = value
|
24
|
+
end
|
25
|
+
opt.on("--skip-tasks", "Don't add friendly_id Rake tasks to lib/tasks") do |value|
|
26
|
+
options[:skip_tasks] = value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CreateSlugs < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :slugs do |t|
|
4
|
+
t.string :name
|
5
|
+
t.integer :sluggable_id
|
6
|
+
t.integer :sequence, :null => false, :default => 1
|
7
|
+
t.string :sluggable_type, :limit => 40
|
8
|
+
t.string :scope
|
9
|
+
t.datetime :created_at
|
10
|
+
end
|
11
|
+
add_index :slugs, :sluggable_id
|
12
|
+
add_index :slugs, [:name, :sluggable_type, :sequence, :scope], :name => "index_slugs_on_n_s_s_and_s", :unique => true
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
drop_table :slugs
|
17
|
+
end
|
18
|
+
end
|
data/lib/friendly_id.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require "babosa"
|
2
|
+
require "forwardable"
|
3
|
+
require "friendly_id/slug_string"
|
4
|
+
require "friendly_id/configuration"
|
5
|
+
require "friendly_id/status"
|
6
|
+
require "friendly_id/slugged"
|
7
|
+
|
8
|
+
# FriendlyId is a comprehensive Ruby library for slugging and permalinks with
|
9
|
+
# ActiveRecord.
|
10
|
+
# @author Norman Clarke
|
11
|
+
# @author Emilio Tagua
|
12
|
+
# @author Adrian Mugnolo
|
13
|
+
module FriendlyId
|
14
|
+
|
15
|
+
# An error based on this class is raised when slug generation fails
|
16
|
+
class SlugGenerationError < StandardError ; end
|
17
|
+
|
18
|
+
# Raised when the slug text is blank.
|
19
|
+
class BlankError < SlugGenerationError ; end
|
20
|
+
|
21
|
+
# Raised when the slug text is reserved.
|
22
|
+
class ReservedError < SlugGenerationError ; end
|
23
|
+
|
24
|
+
module Base
|
25
|
+
# Set up a model to use a friendly_id. This method accepts a hash with
|
26
|
+
# {FriendlyId::Configuration several possible options}.
|
27
|
+
#
|
28
|
+
# @param [#to_sym] method The column or method that should be used as the
|
29
|
+
# basis of the friendly_id string.
|
30
|
+
#
|
31
|
+
# @param [Hash] options For valid configuration options, see
|
32
|
+
# {FriendlyId::Configuration}.
|
33
|
+
#
|
34
|
+
# @example
|
35
|
+
#
|
36
|
+
# class User < ActiveRecord::Base
|
37
|
+
# has_friendly_id :user_name
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# class Post < ActiveRecord::Base
|
41
|
+
# has_friendly_id :title, :use_slug => true, :approximate_ascii => true
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# @see FriendlyId::Configuration
|
45
|
+
def has_friendly_id(method, options = {})
|
46
|
+
raise NotImplementedError
|
47
|
+
end
|
48
|
+
|
49
|
+
# Does the model class use the FriendlyId plugin?
|
50
|
+
def uses_friendly_id?
|
51
|
+
respond_to? :friendly_id_config
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
class String
|
58
|
+
def parse_friendly_id(separator = nil)
|
59
|
+
separator ||= FriendlyId::Configuration::DEFAULTS[:sequence_separator]
|
60
|
+
name, sequence = split(/#{Regexp.escape(separator)}(\d+)?\z/)
|
61
|
+
return name, (sequence ||= 1).to_i
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class Object
|
66
|
+
|
67
|
+
# Is the object a friendly id? Note that the return value here is
|
68
|
+
# +false+ if the +id+ is definitely not friendly, and +nil+ if it can
|
69
|
+
# not be determined.
|
70
|
+
# The return value will be:
|
71
|
+
# * +true+ - if the id is definitely friendly (i.e., a string with non-numeric characters)
|
72
|
+
# * +false+ - if the id is definitely unfriendly (i.e., an Integer, a model instance, etc.)
|
73
|
+
# * +nil+ - if it can not be determined (i.e., a numeric string like "206".)
|
74
|
+
# @return [true, false, nil]
|
75
|
+
# @see #unfriendly?
|
76
|
+
def friendly_id?
|
77
|
+
if kind_of?(Integer) or kind_of?(Symbol) or self.class.respond_to? :friendly_id_config
|
78
|
+
false
|
79
|
+
elsif to_i.to_s != to_s
|
80
|
+
true
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Is the object a numeric id?
|
85
|
+
# @return [true, false, nil] +true+ if definitely unfriendly, +false+ if
|
86
|
+
# definitely friendly, else +nil+.
|
87
|
+
# @see #friendly?
|
88
|
+
def unfriendly_id?
|
89
|
+
val = friendly_id? ; !val unless val.nil?
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
require "friendly_id/railtie" if defined?(Rails) && Rails.version >= "3"
|