friendly_id 3.3.0.rc1 → 3.3.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog.md +1 -0
- data/Guide.md +8 -45
- data/README.md +15 -5
- data/lib/friendly_id/active_record.rb +7 -24
- data/lib/friendly_id/active_record_adapter/simple_model.rb +0 -1
- data/lib/friendly_id/active_record_adapter/slug.rb +1 -2
- data/lib/friendly_id/active_record_adapter/slugged_model.rb +0 -1
- data/lib/friendly_id/version.rb +1 -1
- data/test/active_record_adapter/ar_test_helper.rb +1 -2
- metadata +10 -8
- data/lib/friendly_id/active_record_adapter/finders.rb +0 -148
data/Changelog.md
CHANGED
@@ -8,6 +8,7 @@ suggestions, ideas and improvements to FriendlyId.
|
|
8
8
|
|
9
9
|
## 3.3.0 (NOT_RELEASED_YET)
|
10
10
|
|
11
|
+
* Support for Active Record 2.3 dropped
|
11
12
|
* Convert blank slugs to nil automatically ([Gabe da Silveira ](https://github.com/dasil003))
|
12
13
|
* Compatibility with Active Record 3.1 ([Andrew White](https://github.com/pixeltrix))
|
13
14
|
* Gemspec compatibility with RubyGems 1.7 ([Philip Arndt](https://github.com/parndt))
|
data/Guide.md
CHANGED
@@ -69,48 +69,26 @@ feature. These features are explained in detail {file:Guide.md#features below}.
|
|
69
69
|
|
70
70
|
## Installation
|
71
71
|
|
72
|
-
|
73
|
-
with Rails 2.3.x. and 3.0.
|
74
|
-
|
75
|
-
### As a Gem
|
72
|
+
### Gem installation
|
76
73
|
|
77
74
|
gem install friendly_id
|
78
75
|
|
79
|
-
#### Rails 2.3.x
|
80
|
-
|
81
|
-
After installing the gem, add an entry in environment.rb:
|
82
|
-
|
83
|
-
config.gem "friendly_id", :version => "~> 3.2.1"
|
84
|
-
|
85
|
-
### Rails 3.0
|
86
|
-
|
87
76
|
After installing the gem, add an entry in the Gemfile:
|
88
77
|
|
89
|
-
gem "friendly_id", "~> 3.
|
78
|
+
gem "friendly_id", "~> 3.3.0"
|
90
79
|
|
91
|
-
###
|
80
|
+
### Roadmap
|
92
81
|
|
93
|
-
|
82
|
+
FriendlyId 3.3 is now in **long term maintenance mode.** It will continue to be
|
83
|
+
supported and maintained indefinitely, but no new features will be added to it.
|
94
84
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
installation. Whenever possible, install as a gem instead. Plugin support may
|
99
|
-
eventually be removed in a future version.
|
100
|
-
|
101
|
-
### Future Compatibility
|
102
|
-
|
103
|
-
FriendlyId will always remain compatible with the current release of Rails, and
|
104
|
-
at least one stable release behind. That means that support for 2.3.x will not be
|
105
|
-
dropped until a stable release of 3.1 is out, or possibly longer.
|
85
|
+
[FriendlyId 4.0](https://github.com/norman/friendly_id/tree/4.0.0) is a
|
86
|
+
ground-up rewrite of FriendlyId, and is the project's future, and will be
|
87
|
+
released by September, 2011.
|
106
88
|
|
107
89
|
### Setup
|
108
90
|
|
109
|
-
After installing either as a gem or plugin, run:
|
110
|
-
|
111
|
-
|
112
91
|
rails generate friendly_id
|
113
|
-
# or "./script generate friendly_id" on Rails 2.3
|
114
92
|
rake db:migrate
|
115
93
|
|
116
94
|
This will install the Rake tasks and slug migration for FriendlyId. If you are
|
@@ -632,21 +610,6 @@ own solution is unlikely to be any faster than FriendlyId with cached slugs
|
|
632
610
|
enabled. But if it is, then your patches would be very welcome!
|
633
611
|
|
634
612
|
|
635
|
-
activerecord (2.3.8)
|
636
|
-
ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.4.0]
|
637
|
-
friendly_id (3.1.4)
|
638
|
-
sqlite3-ruby (1.3.1)
|
639
|
-
sqlite3 3.6.12 in-memory database
|
640
|
-
|
641
|
-
| DEFAULT | NO_SLUG | SLUG | CACHED_SLUG |
|
642
|
-
------------------------------------------------------------------------------------------------
|
643
|
-
find model by id x1000 | 0.370 | 0.503 | 0.940 | 0.562 |
|
644
|
-
find model using array of ids x1000 | 0.612 | 0.615 | 1.054 | 0.957 |
|
645
|
-
find model using id, then to_param x1000 | 0.374 | 0.535 | 1.396 | 0.567 |
|
646
|
-
================================================================================================
|
647
|
-
Total | 1.356 | 1.653 | 3.390 | 2.086 |
|
648
|
-
|
649
|
-
|
650
613
|
activerecord (3.0.0)
|
651
614
|
ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.4.0]
|
652
615
|
friendly_id (3.1.4)
|
data/README.md
CHANGED
@@ -19,7 +19,20 @@ versioning, scoped slugs, reserved words, custom slug generators, and
|
|
19
19
|
excellent Unicode support. For complete information on using FriendlyId,
|
20
20
|
please see the [FriendlyId Guide](http://norman.github.com/friendly_id/file.Guide.html).
|
21
21
|
|
22
|
-
|
22
|
+
## Compatibility
|
23
|
+
|
24
|
+
FriendlyId 3.3.0 is compatible with Active Record 3.0 and 3.1.
|
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.
|
32
|
+
|
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
36
|
|
24
37
|
## Docs, Info and Support
|
25
38
|
|
@@ -31,9 +44,6 @@ FriendlyId is compatible with Active Record **2.3.x** and **3.0**.
|
|
31
44
|
|
32
45
|
## Rails Quickstart
|
33
46
|
|
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
47
|
gem install friendly_id
|
38
48
|
|
39
49
|
rails new my_app
|
@@ -41,7 +51,7 @@ continue to support 2.3.x until Rails 3.1 is released.
|
|
41
51
|
cd my_app
|
42
52
|
|
43
53
|
# add to Gemfile
|
44
|
-
gem "friendly_id", "~> 3.
|
54
|
+
gem "friendly_id", "~> 3.3.0"
|
45
55
|
|
46
56
|
rails generate friendly_id
|
47
57
|
rails generate scaffold user name:string cached_slug:string
|
@@ -1,22 +1,13 @@
|
|
1
1
|
module FriendlyId
|
2
2
|
|
3
|
-
# Are we running on ActiveRecord 3 or higher?
|
4
|
-
def self.on_ar3?
|
5
|
-
ActiveRecord::VERSION::STRING >= "3"
|
6
|
-
end
|
7
|
-
|
8
3
|
module ActiveRecordAdapter
|
9
4
|
|
10
5
|
include FriendlyId::Base
|
11
6
|
|
12
7
|
def has_friendly_id(method, options = {})
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
else
|
17
|
-
class_inheritable_accessor :friendly_id_config
|
18
|
-
write_inheritable_attribute :friendly_id_config, Configuration.new(self, method, options)
|
19
|
-
end
|
8
|
+
|
9
|
+
class_attribute :friendly_id_config
|
10
|
+
self.friendly_id_config = Configuration.new(self, method, options)
|
20
11
|
|
21
12
|
if friendly_id_config.use_slug?
|
22
13
|
include SluggedModel
|
@@ -47,7 +38,6 @@ end
|
|
47
38
|
|
48
39
|
require "friendly_id/active_record_adapter/relation"
|
49
40
|
require "friendly_id/active_record_adapter/configuration"
|
50
|
-
require "friendly_id/active_record_adapter/finders"
|
51
41
|
require "friendly_id/active_record_adapter/simple_model"
|
52
42
|
require "friendly_id/active_record_adapter/slugged_model"
|
53
43
|
require "friendly_id/active_record_adapter/slug"
|
@@ -56,18 +46,11 @@ require "friendly_id/active_record_adapter/tasks"
|
|
56
46
|
module ActiveRecord
|
57
47
|
class Base
|
58
48
|
extend FriendlyId::ActiveRecordAdapter
|
59
|
-
unless FriendlyId.on_ar3?
|
60
|
-
class << self
|
61
|
-
VALID_FIND_OPTIONS << :scope
|
62
|
-
end
|
63
|
-
end
|
64
49
|
end
|
65
50
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
include FriendlyId::ActiveRecordAdapter::Relation
|
71
|
-
end
|
51
|
+
class Relation
|
52
|
+
alias find_one_without_friendly find_one
|
53
|
+
alias find_some_without_friendly find_some
|
54
|
+
include FriendlyId::ActiveRecordAdapter::Relation
|
72
55
|
end
|
73
56
|
end
|
@@ -10,7 +10,6 @@ module FriendlyId
|
|
10
10
|
validates_presence_of column, :unless => :skip_friendly_id_validations
|
11
11
|
validates_length_of column, :maximum => friendly_id_config.max_length, :unless => :skip_friendly_id_validations
|
12
12
|
after_update :update_scopes
|
13
|
-
extend FriendlyId::ActiveRecordAdapter::Finders unless FriendlyId.on_ar3?
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
@@ -2,11 +2,10 @@
|
|
2
2
|
class Slug < ::ActiveRecord::Base
|
3
3
|
attr_writer :sluggable
|
4
4
|
attr_accessible :name, :scope, :sluggable, :sequence
|
5
|
-
def self.named_scope(*args, &block) scope(*args, &block) end if FriendlyId.on_ar3?
|
6
5
|
table_name = "slugs"
|
7
6
|
before_save :enable_name_reversion, :set_sequence
|
8
7
|
validate :validate_name
|
9
|
-
|
8
|
+
scope :similar_to, lambda {|slug| {:conditions => {
|
10
9
|
:name => slug.name,
|
11
10
|
:scope => slug.scope,
|
12
11
|
:sluggable_type => slug.sluggable_type
|
data/lib/friendly_id/version.rb
CHANGED
@@ -108,8 +108,7 @@ end
|
|
108
108
|
# A model that uses default slug settings and has a named scope
|
109
109
|
class Post < ActiveRecord::Base
|
110
110
|
has_friendly_id :name, :use_slug => true
|
111
|
-
|
112
|
-
named_scope :published, :conditions => { :published => true }
|
111
|
+
scope :published, :conditions => { :published => true }
|
113
112
|
end
|
114
113
|
|
115
114
|
# Model that uses a custom table name
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: friendly_id
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 6
|
5
|
-
version: 3.3.0.
|
5
|
+
version: 3.3.0.rc2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Norman Clarke
|
@@ -12,11 +12,10 @@ autorequire:
|
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
14
|
|
15
|
-
date: 2011-07-
|
15
|
+
date: 2011-07-14 00:00:00 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: babosa
|
19
|
-
prerelease: false
|
20
19
|
requirement: &id001 !ruby/object:Gem::Requirement
|
21
20
|
none: false
|
22
21
|
requirements:
|
@@ -24,10 +23,10 @@ dependencies:
|
|
24
23
|
- !ruby/object:Gem::Version
|
25
24
|
version: 0.3.0
|
26
25
|
type: :runtime
|
26
|
+
prerelease: false
|
27
27
|
version_requirements: *id001
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: activerecord
|
30
|
-
prerelease: false
|
31
30
|
requirement: &id002 !ruby/object:Gem::Requirement
|
32
31
|
none: false
|
33
32
|
requirements:
|
@@ -35,10 +34,10 @@ dependencies:
|
|
35
34
|
- !ruby/object:Gem::Version
|
36
35
|
version: "3.0"
|
37
36
|
type: :development
|
37
|
+
prerelease: false
|
38
38
|
version_requirements: *id002
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
40
|
name: mocha
|
41
|
-
prerelease: false
|
42
41
|
requirement: &id003 !ruby/object:Gem::Requirement
|
43
42
|
none: false
|
44
43
|
requirements:
|
@@ -46,10 +45,10 @@ dependencies:
|
|
46
45
|
- !ruby/object:Gem::Version
|
47
46
|
version: "0.9"
|
48
47
|
type: :development
|
48
|
+
prerelease: false
|
49
49
|
version_requirements: *id003
|
50
50
|
- !ruby/object:Gem::Dependency
|
51
51
|
name: sqlite3
|
52
|
-
prerelease: false
|
53
52
|
requirement: &id004 !ruby/object:Gem::Requirement
|
54
53
|
none: false
|
55
54
|
requirements:
|
@@ -57,6 +56,7 @@ dependencies:
|
|
57
56
|
- !ruby/object:Gem::Version
|
58
57
|
version: "1.3"
|
59
58
|
type: :development
|
59
|
+
prerelease: false
|
60
60
|
version_requirements: *id004
|
61
61
|
description: " FriendlyId is the \"Swiss Army bulldozer\" of slugging and permalink plugins\n for Ruby on Rails. It allows you to create pretty URL's and work with\n human-friendly strings as if they were numeric ids for ActiveRecord models.\n"
|
62
62
|
email:
|
@@ -72,7 +72,6 @@ extra_rdoc_files: []
|
|
72
72
|
files:
|
73
73
|
- lib/friendly_id/active_record.rb
|
74
74
|
- lib/friendly_id/active_record_adapter/configuration.rb
|
75
|
-
- lib/friendly_id/active_record_adapter/finders.rb
|
76
75
|
- lib/friendly_id/active_record_adapter/relation.rb
|
77
76
|
- lib/friendly_id/active_record_adapter/simple_model.rb
|
78
77
|
- lib/friendly_id/active_record_adapter/slug.rb
|
@@ -132,7 +131,7 @@ files:
|
|
132
131
|
homepage: http://norman.github.com/friendly_id
|
133
132
|
licenses: []
|
134
133
|
|
135
|
-
post_install_message:
|
134
|
+
post_install_message: " FriendlyId 3.3.x is now in long-term maintanence. For new projects with\n Rails 3.1.x please consider using 4.0, which is under active development:\n\n https://github.com/norman/friendly_id/tree/4.0.0\n"
|
136
135
|
rdoc_options: []
|
137
136
|
|
138
137
|
require_paths:
|
@@ -142,6 +141,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
142
141
|
requirements:
|
143
142
|
- - ">="
|
144
143
|
- !ruby/object:Gem::Version
|
144
|
+
hash: -1068692454411674602
|
145
|
+
segments:
|
146
|
+
- 0
|
145
147
|
version: "0"
|
146
148
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
149
|
none: false
|
@@ -1,148 +0,0 @@
|
|
1
|
-
module FriendlyId
|
2
|
-
module ActiveRecordAdapter
|
3
|
-
module Finders
|
4
|
-
|
5
|
-
class Find
|
6
|
-
extend Forwardable
|
7
|
-
def_delegators :@klass, :scoped, :friendly_id_config, :quoted_table_name, :table_name, :primary_key,
|
8
|
-
:connection, :name, :sanitize_sql
|
9
|
-
def_delegators :fc, :use_slugs?, :cache_column, :cache_column?
|
10
|
-
alias fc friendly_id_config
|
11
|
-
|
12
|
-
attr :klass
|
13
|
-
attr :id
|
14
|
-
attr :options
|
15
|
-
attr :result
|
16
|
-
attr :friendly_ids
|
17
|
-
attr :unfriendly_ids
|
18
|
-
|
19
|
-
def initialize(klass, id, options)
|
20
|
-
@klass = klass
|
21
|
-
@id = id
|
22
|
-
@options = options
|
23
|
-
if options[:scope]
|
24
|
-
raise "The :scope finder option has been removed from FriendlyId 3.2.0 " +
|
25
|
-
"https://github.com/norman/friendly_id/issues#issue/88"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def find_one
|
30
|
-
return find_one_with_cached_slug if !fc.scope? && cache_column?
|
31
|
-
return find_one_with_slug if use_slugs?
|
32
|
-
@result = scoped(:conditions => ["#{table_name}.#{fc.column} = ?", id]).first(options)
|
33
|
-
assign_status
|
34
|
-
end
|
35
|
-
|
36
|
-
def find_some
|
37
|
-
parse_ids!
|
38
|
-
scope = some_friendly_scope
|
39
|
-
if use_slugs? && @friendly_ids.present?
|
40
|
-
scope = scope.scoped(:joins => :slugs)
|
41
|
-
end
|
42
|
-
options[:readonly] = false unless options[:readonly]
|
43
|
-
@result = scope.all(options).uniq
|
44
|
-
validate_expected_size!
|
45
|
-
@result.each { |record| record.friendly_id_status.name = id }
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def find_one_with_cached_slug
|
51
|
-
@result = scoped(:conditions => ["#{table_name}.#{cache_column} = ?", id]).first(options)
|
52
|
-
assign_status or find_one_with_slug
|
53
|
-
end
|
54
|
-
|
55
|
-
def find_one_with_slug
|
56
|
-
name, seq = id.to_s.parse_friendly_id
|
57
|
-
scope = scoped(:joins => :slugs, :conditions => {:slugs => {:name => name, :sequence => seq}})
|
58
|
-
options[:readonly] = false unless options[:readonly]
|
59
|
-
@result = scope.first(options)
|
60
|
-
assign_status
|
61
|
-
end
|
62
|
-
|
63
|
-
def parse_ids!
|
64
|
-
@id = id.uniq.map do |member|
|
65
|
-
if member.respond_to?(:friendly_id_config)
|
66
|
-
member.id
|
67
|
-
else
|
68
|
-
member
|
69
|
-
end
|
70
|
-
end
|
71
|
-
@friendly_ids, @unfriendly_ids = @id.partition {|member| member.friendly_id?}
|
72
|
-
end
|
73
|
-
|
74
|
-
def validate_expected_size!
|
75
|
-
expected = expected_size
|
76
|
-
return if @result.size == expected
|
77
|
-
message = "Couldn't find all %s with IDs (%s) AND %s (found %d results, but was looking for %d)" % [
|
78
|
-
name.pluralize,
|
79
|
-
id.join(', '),
|
80
|
-
sanitize_sql(options[:conditions]),
|
81
|
-
result.size,
|
82
|
-
expected
|
83
|
-
]
|
84
|
-
raise ActiveRecord::RecordNotFound, message
|
85
|
-
end
|
86
|
-
|
87
|
-
def assign_status
|
88
|
-
return unless @result
|
89
|
-
name, seq = @id.to_s.parse_friendly_id
|
90
|
-
@result.friendly_id_status.name = name
|
91
|
-
@result.friendly_id_status.sequence = seq if use_slugs?
|
92
|
-
@result
|
93
|
-
end
|
94
|
-
|
95
|
-
def expected_size
|
96
|
-
if options[:limit] && @id.size > options[:limit]
|
97
|
-
options[:limit]
|
98
|
-
else
|
99
|
-
@id.size
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def some_friendly_scope
|
104
|
-
query_slugs = use_slugs? && !cache_column?
|
105
|
-
pkey = "#{quoted_table_name}.#{primary_key}"
|
106
|
-
column = "#{table_name}.#{cache_column || fc.column}"
|
107
|
-
if @unfriendly_ids.present?
|
108
|
-
conditions = ["#{pkey} IN (?)", @unfriendly_ids]
|
109
|
-
if @friendly_ids.present?
|
110
|
-
if query_slugs
|
111
|
-
conditions[0] << " OR #{some_slugged_conditions}"
|
112
|
-
else
|
113
|
-
conditions[0] << " OR #{column} IN (?)"
|
114
|
-
conditions << @friendly_ids
|
115
|
-
end
|
116
|
-
end
|
117
|
-
elsif @friendly_ids.present?
|
118
|
-
conditions = query_slugs ? some_slugged_conditions : ["#{column} IN (?)", @friendly_ids]
|
119
|
-
end
|
120
|
-
scoped(:conditions => conditions)
|
121
|
-
end
|
122
|
-
|
123
|
-
def some_slugged_conditions
|
124
|
-
return unless @friendly_ids.present?
|
125
|
-
slug_table = Slug.quoted_table_name
|
126
|
-
fragment = "(#{slug_table}.name = %s AND #{slug_table}.sequence = %d)"
|
127
|
-
@friendly_ids.inject(nil) do |clause, id|
|
128
|
-
name, seq = id.parse_friendly_id
|
129
|
-
string = fragment % [connection.quote(name), seq]
|
130
|
-
clause ? clause + " OR #{string}" : string
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def find_one(id, options)
|
136
|
-
return super if id.blank? || id.unfriendly_id?
|
137
|
-
finder = Find.new(self, id, options)
|
138
|
-
finder.find_one or super
|
139
|
-
end
|
140
|
-
|
141
|
-
def find_some(ids, options)
|
142
|
-
return super if ids.empty?
|
143
|
-
finder = Find.new(self, ids, options)
|
144
|
-
finder.find_some
|
145
|
-
end
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|