friendly_id_globalize3 3.2.0
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.
- 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"
|