friendly_id 3.2.0.beta1 → 3.2.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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"
|