friendly_id 3.2.0.beta1 → 3.2.0.rc1
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 +2 -0
- data/Guide.md +32 -33
- data/lib/friendly_id/active_record.rb +8 -2
- data/lib/friendly_id/active_record_adapter/finders.rb +4 -0
- data/lib/friendly_id/active_record_adapter/relation.rb +9 -1
- data/lib/friendly_id/active_record_adapter/tasks.rb +9 -4
- data/lib/friendly_id/slug_string.rb +1 -1
- data/lib/friendly_id/version.rb +1 -1
- data/lib/tasks/friendly_id.rake +2 -2
- data/test/active_record_adapter/scoped_model_test.rb +6 -0
- metadata +6 -6
data/Changelog.md
CHANGED
@@ -8,8 +8,10 @@ suggestions, ideas and improvements to FriendlyId.
|
|
8
8
|
|
9
9
|
## 3.2.0 (NOT RELEASED YET)
|
10
10
|
|
11
|
+
* Fixed deprecation on Rails edge. Thanks [slbug](http://github.com/slbug)
|
11
12
|
* Removes `:scope` as a find parameter, allowing more flexible finds with
|
12
13
|
scoped records.
|
14
|
+
* Improve logic of `friendly_id:redo_slugs` to support models with non-numeric ids. (thanks Oleksandr Petrov)
|
13
15
|
|
14
16
|
## 3.1.8 (2010-11-22)
|
15
17
|
|
data/Guide.md
CHANGED
@@ -425,12 +425,16 @@ Note that this method is **not** used by slugged models.
|
|
425
425
|
|
426
426
|
## Scoped Slugs
|
427
427
|
|
428
|
+
_Note that in FriendlyId prior to 3.2.0, you could specify a non-standard
|
429
|
+
`:scope` argument on finds. This feature has been removed in 3.2.0 in favor of
|
430
|
+
the query stategies described below._
|
431
|
+
|
428
432
|
FriendlyId can generate unique slugs within a given scope. For example, assume
|
429
|
-
you have an application that displays restaurants. Without scoped slugs, if
|
430
|
-
|
431
|
-
"joes-diner--2" as its friendly_id. Using scoped allows you to keep the
|
432
|
-
|
433
|
-
|
433
|
+
you have an application that displays restaurants. Without scoped slugs, if two
|
434
|
+
restaurants are named "Joe's Diner," the second one will end up with
|
435
|
+
"joes-diner--2" as its friendly_id. Using scoped allows you to keep the slug
|
436
|
+
names unique for each city, so that the second "Joe's Diner" can also have the
|
437
|
+
slug "joes-diner", as long as it's located in a different city:
|
434
438
|
|
435
439
|
class Restaurant < ActiveRecord::Base
|
436
440
|
belongs_to :city
|
@@ -442,11 +446,9 @@ the slug "joes-diner" if it's located in a different city:
|
|
442
446
|
has_friendly_id :name, :use_slug => true
|
443
447
|
end
|
444
448
|
|
445
|
-
|
446
|
-
|
449
|
+
City.find("seattle").restaurants.find("joes-diner")
|
450
|
+
City.find("chicago").restaurants.find("joes-diner")
|
447
451
|
|
448
|
-
City.find("seattle").restaurants.find("joes-diner") # returns 1 record
|
449
|
-
City.find("chicago").restaurants.find("joes-diner") # returns 1 record
|
450
452
|
|
451
453
|
The value for the `:scope` key in your model can be a custom method you
|
452
454
|
define, or the name of a relation. If it's the name of a relation, then the
|
@@ -456,6 +458,12 @@ its `to_param` method returns its friendly_id: "chicago" or "seattle".
|
|
456
458
|
|
457
459
|
### Complications with Scoped Slugs
|
458
460
|
|
461
|
+
#### Scoped Models and Cached Slugs
|
462
|
+
|
463
|
+
If you want to use cached slugs with scoped models, be sure not to create a unique index on the
|
464
|
+
`cached_slug` column.
|
465
|
+
|
466
|
+
|
459
467
|
#### Finding Records by friendly\_id
|
460
468
|
|
461
469
|
If you are using scopes your friendly ids may not be unique, so a simple find like
|
@@ -475,12 +483,10 @@ either query as a relation, or specify the scope in your query conditions:
|
|
475
483
|
|
476
484
|
#### Finding All Records That Match a Scoped ID
|
477
485
|
|
478
|
-
If you want to find all records with a
|
486
|
+
If you want to find all records with a particular friendly\_id regardless of scope,
|
479
487
|
the easiest way is to use cached slugs and query this column directly:
|
480
488
|
|
481
489
|
Restaurant.find_all_by_cached_slug("joes-diner")
|
482
|
-
# Another option, with Active Record 3.x
|
483
|
-
Restaurant.where(:cached_slug => "joes-diner")
|
484
490
|
|
485
491
|
|
486
492
|
If you're not using cached slugs, then this is slightly more complicated, but
|
@@ -494,38 +500,31 @@ still doable:
|
|
494
500
|
|
495
501
|
#### Updating a Relation's Scoped Slugs
|
496
502
|
|
497
|
-
When using a relation as the scope, updating the relation will update the
|
498
|
-
|
499
|
-
|
500
|
-
|
503
|
+
When using a relation as the scope, updating the relation will update the slugs,
|
504
|
+
but only if both models have specified the relationship. In the above example,
|
505
|
+
updates to City will update the slugs for Restaurant because City specifies that
|
506
|
+
it `has_many :restaurants`.
|
501
507
|
|
502
508
|
### Routes for Scoped Models
|
503
509
|
|
504
|
-
Note that FriendlyId does not set up any routes for scoped models; you must
|
505
|
-
|
506
|
-
this up:
|
510
|
+
Note that FriendlyId does not set up any routes for scoped models; you must do
|
511
|
+
this yourself in your application. Here's an example of one way to set this up:
|
507
512
|
|
508
513
|
# in routes.rb
|
509
|
-
|
510
|
-
|
514
|
+
resources :cities do
|
515
|
+
resources :restaurants
|
516
|
+
end
|
511
517
|
|
512
518
|
# in views
|
513
|
-
link_to 'Show',
|
519
|
+
<%= link_to 'Show', [@city, @restaurant] %>
|
514
520
|
|
515
521
|
# in controllers
|
516
522
|
@city = City.find(params[:city_id])
|
517
|
-
@restaurant = @city.
|
518
|
-
|
519
|
-
### Scoped Models and Cached Slugs
|
520
|
-
|
521
|
-
If you want to use cached slugs with scoped models, be sure not to create a unique index on the
|
522
|
-
`cached_slug` column.
|
523
|
-
|
524
|
-
### Scoped Models in FriendyId Before 3.2.0
|
523
|
+
@restaurant = @city.restaurants.find(params[:id])
|
525
524
|
|
526
|
-
|
527
|
-
|
528
|
-
|
525
|
+
# URL's:
|
526
|
+
http://example.org/cities/seattle/restaurants/joes-diner
|
527
|
+
http://example.org/cities/chicago/restaurants/joes-diner
|
529
528
|
|
530
529
|
|
531
530
|
## FriendlyId Rake Tasks
|
@@ -10,8 +10,14 @@ module FriendlyId
|
|
10
10
|
include FriendlyId::Base
|
11
11
|
|
12
12
|
def has_friendly_id(method, options = {})
|
13
|
-
|
14
|
-
|
13
|
+
if FriendlyId.on_ar3?
|
14
|
+
class_attribute :friendly_id_config
|
15
|
+
self.friendly_id_config = Configuration.new(self, method, options)
|
16
|
+
else
|
17
|
+
class_inheritable_accessor :friendly_id_config
|
18
|
+
write_inheritable_attribute :friendly_id_config, Configuration.new(self, method, options)
|
19
|
+
end
|
20
|
+
|
15
21
|
if friendly_id_config.use_slug?
|
16
22
|
include SluggedModel
|
17
23
|
else
|
@@ -20,6 +20,10 @@ module FriendlyId
|
|
20
20
|
@klass = klass
|
21
21
|
@id = id
|
22
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
|
23
27
|
end
|
24
28
|
|
25
29
|
def find_one
|
@@ -133,6 +133,14 @@ module FriendlyId
|
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
136
|
+
def apply_finder_options(options)
|
137
|
+
if options[:scope]
|
138
|
+
raise "The :scope finder option has been removed from FriendlyId 3.2.0 " +
|
139
|
+
"https://github.com/norman/friendly_id/issues#issue/88"
|
140
|
+
end
|
141
|
+
super
|
142
|
+
end
|
143
|
+
|
136
144
|
protected
|
137
145
|
|
138
146
|
def find_one(id)
|
@@ -154,4 +162,4 @@ module FriendlyId
|
|
154
162
|
end
|
155
163
|
end
|
156
164
|
end
|
157
|
-
end
|
165
|
+
end
|
@@ -26,15 +26,20 @@ module FriendlyId
|
|
26
26
|
|
27
27
|
def make_slugs
|
28
28
|
validate_uses_slugs
|
29
|
-
|
30
|
-
|
29
|
+
options = {
|
30
|
+
:include => :slug,
|
31
|
+
:limit => (ENV["LIMIT"] || 100).to_i,
|
32
|
+
:offset => 0,
|
33
|
+
:order => ENV["ORDER"] || "#{klass.table_name}.id ASC",
|
34
|
+
}.merge(task_options || {})
|
35
|
+
|
31
36
|
while records = find(:all, options) do
|
32
37
|
break if records.size == 0
|
33
38
|
records.each do |record|
|
34
|
-
record.save(:validate => false)
|
39
|
+
record.save(:validate => false) unless record.slug?
|
35
40
|
yield(record) if block_given?
|
36
41
|
end
|
37
|
-
options[:
|
42
|
+
options[:offset] += options[:limit]
|
38
43
|
end
|
39
44
|
end
|
40
45
|
|
@@ -17,7 +17,7 @@ module FriendlyId
|
|
17
17
|
# @raise FriendlyId::ReservedError
|
18
18
|
def validate_for!(config)
|
19
19
|
truncate_bytes!(config.max_length)
|
20
|
-
raise FriendlyId::BlankError if
|
20
|
+
raise FriendlyId::BlankError if empty?
|
21
21
|
raise FriendlyId::ReservedError if config.reserved?(self)
|
22
22
|
self
|
23
23
|
end
|
data/lib/friendly_id/version.rb
CHANGED
data/lib/tasks/friendly_id.rake
CHANGED
@@ -2,7 +2,7 @@ namespace :friendly_id do
|
|
2
2
|
desc "Make slugs for a model."
|
3
3
|
task :make_slugs => :environment do
|
4
4
|
FriendlyId::TaskRunner.new.make_slugs do |record|
|
5
|
-
puts "
|
5
|
+
puts "#{record.class}(#{record.id}): friendly_id set to '#{record.slug.name}'" if record.slug
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
@@ -16,4 +16,4 @@ namespace :friendly_id do
|
|
16
16
|
task :remove_old_slugs => :environment do
|
17
17
|
FriendlyId::TaskRunner.new.delete_old_slugs
|
18
18
|
end
|
19
|
-
end
|
19
|
+
end
|
@@ -26,6 +26,12 @@ module FriendlyId
|
|
26
26
|
Tourist.delete_all
|
27
27
|
end
|
28
28
|
|
29
|
+
test "As of 3.2.0, should raise error if :scope option is passed" do
|
30
|
+
assert_raise(RuntimeError) do
|
31
|
+
Tourist.find("hello", :scope => "usa")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
29
35
|
test "should not use cached slug column with scopes" do
|
30
36
|
@tourist = Tourist.create!(:name => "John Smith", :country => @usa)
|
31
37
|
@tourist2 = Tourist.create!(:name => "John Smith", :country => @canada)
|
metadata
CHANGED
@@ -6,8 +6,8 @@ version: !ruby/object:Gem::Version
|
|
6
6
|
- 3
|
7
7
|
- 2
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 3.2.0.
|
9
|
+
- rc1
|
10
|
+
version: 3.2.0.rc1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Norman Clarke
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date:
|
20
|
+
date: 2011-01-12 00:00:00 -03:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|
@@ -30,8 +30,8 @@ dependencies:
|
|
30
30
|
segments:
|
31
31
|
- 0
|
32
32
|
- 2
|
33
|
-
-
|
34
|
-
version: 0.2.
|
33
|
+
- 1
|
34
|
+
version: 0.2.1
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: *id001
|
@@ -160,7 +160,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
160
160
|
requirements:
|
161
161
|
- - ">="
|
162
162
|
- !ruby/object:Gem::Version
|
163
|
-
hash: -
|
163
|
+
hash: -1225128914130125951
|
164
164
|
segments:
|
165
165
|
- 0
|
166
166
|
version: "0"
|