friendly_id 3.0.6 → 3.1.0.pre
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 +10 -0
- data/Contributors.md +1 -0
- data/Guide.md +24 -35
- data/README.md +3 -3
- data/Rakefile +0 -5
- data/extras/bench.rb +5 -1
- data/extras/prof.rb +9 -4
- data/lib/friendly_id.rb +35 -7
- data/lib/friendly_id/active_record.rb +32 -17
- data/lib/friendly_id/active_record_adapter/configuration.rb +1 -0
- data/lib/friendly_id/active_record_adapter/finders.rb +136 -130
- data/lib/friendly_id/active_record_adapter/relation.rb +129 -0
- data/lib/friendly_id/active_record_adapter/simple_model.rb +2 -62
- data/lib/friendly_id/active_record_adapter/slug.rb +3 -2
- data/lib/friendly_id/active_record_adapter/slugged_model.rb +13 -145
- data/lib/friendly_id/configuration.rb +1 -1
- data/lib/friendly_id/railtie.rb +2 -2
- data/lib/friendly_id/slug_string.rb +22 -392
- data/lib/friendly_id/slugged.rb +7 -3
- data/lib/friendly_id/test.rb +1 -2
- data/lib/friendly_id/version.rb +3 -3
- data/test/active_record_adapter/ar_test_helper.rb +14 -6
- data/test/active_record_adapter/cached_slug_test.rb +10 -0
- data/test/active_record_adapter/core.rb +15 -0
- data/test/active_record_adapter/slugged.rb +0 -1
- data/test/active_record_adapter/support/models.rb +4 -0
- data/test/active_record_adapter/tasks_test.rb +1 -1
- data/test/friendly_id_test.rb +12 -16
- data/test/test_helper.rb +9 -10
- metadata +18 -16
- data/lib/friendly_id/finders.rb +0 -109
- data/test/slug_string_test.rb +0 -88
data/Changelog.md
CHANGED
@@ -6,6 +6,16 @@ suggestions, ideas and improvements to FriendlyId.
|
|
6
6
|
* Table of Contents
|
7
7
|
{:toc}
|
8
8
|
|
9
|
+
## 3.1.0 (NOT RELEASED)
|
10
|
+
|
11
|
+
* Refactored/simplified Active Record 2 and 3 query code.
|
12
|
+
* Better support for Active Record 3 finds and scopes.
|
13
|
+
* Extract slug handling code into separate gem, [Babosa](http://github.com/norman/babosa).
|
14
|
+
* :max-length option now uses bytes rather than characters.
|
15
|
+
* Fix quoting issue that prevented using a domain- or database-qualified column. (thanks James Cropcho)
|
16
|
+
* Support for Active Record 2.2.x dropped; 2.3 or above is now required.
|
17
|
+
* Fixed a few small errors on Postgres.
|
18
|
+
|
9
19
|
## 3.0.6 (2010-06-10)
|
10
20
|
|
11
21
|
* Fix bad call to apply_mapping on 2.3.
|
data/Contributors.md
CHANGED
data/Guide.md
CHANGED
@@ -131,9 +131,9 @@ for {FriendlyId::Configuration}.
|
|
131
131
|
|
132
132
|
## FriendlyId Strings
|
133
133
|
|
134
|
-
FriendlyId
|
135
|
-
strings
|
136
|
-
to make it more suitable for use in a URL:
|
134
|
+
FriendlyId uses the [Babosa](http://github.com/norman/babosa) library for
|
135
|
+
generating slug strings. When using slugs, FriendlyId/Babosa will automatically
|
136
|
+
modify the slug text to make it more suitable for use in a URL:
|
137
137
|
|
138
138
|
class City < ActiveRecord::Base
|
139
139
|
has_friendly_id :name, :use_slug => true
|
@@ -180,15 +180,9 @@ There are special options for some languages:
|
|
180
180
|
@post.create(:title => "¡Feliz año!")
|
181
181
|
@post.title # will be "feliz-anno"
|
182
182
|
|
183
|
-
### Approximations for Other Languages
|
184
|
-
|
185
|
-
You can add custom approximations for your language by adding Hash of
|
186
|
-
approximations to {FriendlyId::SlugString::APPROXIMATIONS}. The approximations
|
187
|
-
must be listed as Unicode decimal numbers, and arrays of numbers.
|
188
|
-
|
189
183
|
### Unicode Slugs
|
190
184
|
|
191
|
-
By default, any character outside the Unicode
|
185
|
+
By default, any character outside the Unicode Latin character range will be
|
192
186
|
passed through untouched, allowing you to have slugs in Arabic, Japanese,
|
193
187
|
Greek, etc:
|
194
188
|
|
@@ -514,15 +508,6 @@ Before removing any public or protected methods, FriendlyId will deprecate
|
|
514
508
|
them through one major release cycle. Private methods may, however, change at
|
515
509
|
any time.
|
516
510
|
|
517
|
-
## Running the Tests
|
518
|
-
|
519
|
-
FriendlyId uses [Bundler](http://github.com/carlhuda/bundler) to manage its gem
|
520
|
-
dependencies. To run the tests, first make sure you have bundler installed.
|
521
|
-
Then, copy Gemfile.default to Gemfile. If you wish to test against different gem
|
522
|
-
versions than the ones specified in the Gemfile (for example, to test with
|
523
|
-
Postgres or MySQL rather than SQLite3, or to test against different versions of
|
524
|
-
ActiveRecord), then simply modify the Gemfile to suit your dependencies.
|
525
|
-
|
526
511
|
## Some Benchmarks
|
527
512
|
|
528
513
|
These benchmarks can give you an idea of FriendlyId's impact on the
|
@@ -535,27 +520,31 @@ decide not to use FriendlyId for performance reasons, keep in mind that your
|
|
535
520
|
own solution is unlikely to be any faster than FriendlyId with cached slugs
|
536
521
|
enabled. But if it is, then your patches would be very welcome!
|
537
522
|
|
538
|
-
|
539
|
-
activerecord (2.3.
|
540
|
-
|
541
|
-
|
523
|
+
|
524
|
+
activerecord (2.3.8)
|
525
|
+
ruby 1.9.2dev (2010-07-06 revision 28549) [x86_64-darwin10.4.0]
|
526
|
+
friendly_id (3.1.0)
|
527
|
+
sqlite3 3.6.12 in-memory database
|
528
|
+
|
542
529
|
| DEFAULT | NO_SLUG | SLUG | CACHED_SLUG |
|
543
530
|
------------------------------------------------------------------------------------------------
|
544
|
-
find model by id x1000 | 0.
|
545
|
-
find model using array of ids x1000 | 0.
|
546
|
-
find model using id, then to_param x1000 | 0.
|
531
|
+
find model by id x1000 | 0.340 | 0.468 | 0.877 | 0.534 |
|
532
|
+
find model using array of ids x1000 | 0.551 | 0.592 | 0.989 | 0.893 |
|
533
|
+
find model using id, then to_param x1000 | 0.340 | 0.487 | 1.310 | 0.551 |
|
547
534
|
================================================================================================
|
548
|
-
Total | 1.
|
535
|
+
Total | 1.231 | 1.547 | 3.176 | 1.979 |
|
536
|
+
|
537
|
+
|
549
538
|
|
550
|
-
|
551
|
-
|
552
|
-
friendly_id (
|
553
|
-
sqlite3 3.6.
|
539
|
+
activerecord (3.0.0.beta4)
|
540
|
+
ruby 1.9.2dev (2010-07-06 revision 28549) [x86_64-darwin10.4.0]
|
541
|
+
friendly_id (3.1.0)
|
542
|
+
sqlite3 3.6.12 in-memory database
|
554
543
|
|
555
544
|
| DEFAULT | NO_SLUG | SLUG | CACHED_SLUG |
|
556
545
|
------------------------------------------------------------------------------------------------
|
557
|
-
find model by id x1000 | 0.
|
558
|
-
find model using array of ids x1000 | 0.
|
559
|
-
find model using id, then to_param x1000 | 0.
|
546
|
+
find model by id x1000 | 0.495 | 0.608 | 1.519 | 0.641 |
|
547
|
+
find model using array of ids x1000 | 0.708 | 0.722 | 6.483 | 0.782 |
|
548
|
+
find model using id, then to_param x1000 | 0.506 | 0.645 | 2.644 | 0.637 |
|
560
549
|
================================================================================================
|
561
|
-
Total |
|
550
|
+
Total | 1.709 | 1.976 | 10.645 | 2.061 |
|
data/README.md
CHANGED
@@ -19,7 +19,7 @@ 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 {http://norman.github.com/friendly_id/file.Guide.html FriendlyId Guide}.
|
21
21
|
|
22
|
-
FriendlyId is compatible with Rails 2.
|
22
|
+
FriendlyId is compatible with Rails 2.3.x and 3.0.
|
23
23
|
|
24
24
|
## Rails Quickstart
|
25
25
|
|
@@ -30,7 +30,7 @@ FriendlyId is compatible with Rails 2.2.x - 3.0.
|
|
30
30
|
cd my_app
|
31
31
|
|
32
32
|
# add to Gemfile
|
33
|
-
gem "friendly_id", "~> 3.
|
33
|
+
gem "friendly_id", "~> 3.1"
|
34
34
|
|
35
35
|
rails generate friendly_id
|
36
36
|
rails generate scaffold user name:string cached_slug:string
|
@@ -63,8 +63,8 @@ for this project.
|
|
63
63
|
|
64
64
|
If you have a bug to report, please include the following information:
|
65
65
|
|
66
|
+
* **Version information for FriendlyId, Rails and Ruby.**
|
66
67
|
* Stack trace and error message.
|
67
|
-
* Version information for FriendlyId, Rails and Ruby.
|
68
68
|
* Any snippets of relevant model, view or controller code that shows how your
|
69
69
|
are using FriendlyId.
|
70
70
|
|
data/Rakefile
CHANGED
@@ -1,17 +1,12 @@
|
|
1
1
|
require "rake"
|
2
2
|
require "rake/testtask"
|
3
3
|
require "rake/gempackagetask"
|
4
|
-
require "rake/rdoctask"
|
5
4
|
require "rake/clean"
|
6
5
|
|
7
6
|
task :default => :test
|
8
7
|
|
9
8
|
CLEAN << "pkg" << "doc" << "coverage" << ".yardoc"
|
10
9
|
Rake::GemPackageTask.new(eval(File.read("friendly_id.gemspec"))) { |pkg| }
|
11
|
-
Rake::RDocTask.new do |r|
|
12
|
-
r.rdoc_dir = "doc"
|
13
|
-
r.rdoc_files.include "lib/**/*.rb"
|
14
|
-
end
|
15
10
|
|
16
11
|
begin
|
17
12
|
require "yard"
|
data/extras/bench.rb
CHANGED
data/extras/prof.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
$:.unshift File.expand_path("../lib", File.dirname(__FILE__))
|
2
|
+
$:.unshift File.expand_path(File.dirname(__FILE__))
|
3
|
+
$:.uniq!
|
4
|
+
|
5
|
+
require "extras"
|
3
6
|
require 'ruby-prof'
|
4
7
|
|
5
8
|
# RubyProf.measure_mode = RubyProf::MEMORY
|
@@ -10,5 +13,7 @@ RubyProf.start
|
|
10
13
|
end
|
11
14
|
result = RubyProf.stop
|
12
15
|
GC.enable
|
13
|
-
printer = RubyProf::CallTreePrinter.new(result)
|
14
|
-
printer.
|
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"))
|
data/lib/friendly_id.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require "babosa"
|
1
2
|
require "forwardable"
|
2
3
|
require "active_support/core_ext/class/attribute_accessors"
|
3
4
|
begin
|
@@ -7,11 +8,10 @@ rescue MissingSourceFile
|
|
7
8
|
require "active_support/core_ext/blank"
|
8
9
|
end
|
9
10
|
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require File.join(File.dirname(__FILE__), "friendly_id", "slugged")
|
11
|
+
require "friendly_id/slug_string"
|
12
|
+
require "friendly_id/configuration"
|
13
|
+
require "friendly_id/status"
|
14
|
+
require "friendly_id/slugged"
|
15
15
|
|
16
16
|
# FriendlyId is a comprehensive Ruby library for slugging and permalinks with
|
17
17
|
# ActiveRecord.
|
@@ -66,8 +66,36 @@ class String
|
|
66
66
|
def parse_friendly_id(separator = nil)
|
67
67
|
separator ||= FriendlyId::Configuration::DEFAULTS[:sequence_separator]
|
68
68
|
name, sequence = split(/#{Regexp.escape(separator)}(\d+)?\z/)
|
69
|
-
return name, sequence ||=
|
69
|
+
return name, (sequence ||= 1).to_i
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
-
|
73
|
+
class Object
|
74
|
+
|
75
|
+
# Is the object a friendly id? Note that the return value here is
|
76
|
+
# +false+ if the +id+ is definitely not friendly, and +nil+ if it can
|
77
|
+
# not be determined.
|
78
|
+
# The return value will be:
|
79
|
+
# * +true+ - if the id is definitely friendly (i.e., a string with non-numeric characters)
|
80
|
+
# * +false+ - if the id is definitely unfriendly (i.e., an Integer, a model instance, etc.)
|
81
|
+
# * +nil+ - if it can not be determined (i.e., a numeric string like "206".)
|
82
|
+
# @return [true, false, nil]
|
83
|
+
# @see #unfriendly?
|
84
|
+
def friendly_id?
|
85
|
+
if kind_of?(Integer) or kind_of?(Symbol) or self.class.respond_to? :friendly_id_config
|
86
|
+
false
|
87
|
+
elsif to_i.to_s != to_s
|
88
|
+
true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Is the object a numeric id?
|
93
|
+
# @return [true, false, nil] +true+ if definitely unfriendly, +false+ if
|
94
|
+
# definitely friendly, else +nil+.
|
95
|
+
# @see #friendly?
|
96
|
+
def unfriendly_id?
|
97
|
+
val = friendly_id? ; !val unless val.nil?
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
require "friendly_id/railtie" if defined?(Rails) && Rails.version >= "3"
|
@@ -1,12 +1,11 @@
|
|
1
1
|
module FriendlyId
|
2
2
|
|
3
|
-
|
3
|
+
# Are we running on ActiveRecord 3 or higher?
|
4
|
+
def self.on_ar3?
|
5
|
+
ActiveRecord::VERSION::STRING >= "3"
|
6
|
+
end
|
4
7
|
|
5
|
-
|
6
|
-
def self.scope_method
|
7
|
-
ActiveRecord::VERSION::STRING >= "3" ? :scope : :named_scope
|
8
|
-
end
|
9
|
-
end
|
8
|
+
module ActiveRecordAdapter
|
10
9
|
|
11
10
|
include FriendlyId::Base
|
12
11
|
|
@@ -28,8 +27,8 @@ module FriendlyId
|
|
28
27
|
# wish to use +attr_accessible+, you must invoke it BEFORE you invoke
|
29
28
|
# {#has_friendly_id} in your class.
|
30
29
|
def protect_friendly_id_attributes
|
31
|
-
# only protect the column if the class is not already using
|
32
|
-
|
30
|
+
# only protect the column if the class is not already using attr_accessible
|
31
|
+
unless accessible_attributes.present?
|
33
32
|
if friendly_id_config.custom_cache_column?
|
34
33
|
attr_protected friendly_id_config.cache_column
|
35
34
|
end
|
@@ -40,13 +39,29 @@ module FriendlyId
|
|
40
39
|
end
|
41
40
|
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
require "friendly_id/active_record_adapter/relation"
|
43
|
+
require "friendly_id/active_record_adapter/configuration"
|
44
|
+
require "friendly_id/active_record_adapter/finders"
|
45
|
+
require "friendly_id/active_record_adapter/simple_model"
|
46
|
+
require "friendly_id/active_record_adapter/slugged_model"
|
47
|
+
require "friendly_id/active_record_adapter/slug"
|
48
|
+
require "friendly_id/active_record_adapter/tasks"
|
46
49
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
module ActiveRecord
|
51
|
+
class Base
|
52
|
+
extend FriendlyId::ActiveRecordAdapter
|
53
|
+
unless FriendlyId.on_ar3?
|
54
|
+
class << self
|
55
|
+
VALID_FIND_OPTIONS << :scope
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
if defined? Relation
|
61
|
+
class Relation
|
62
|
+
alias find_one_without_friendly find_one
|
63
|
+
alias find_some_without_friendly find_some
|
64
|
+
include FriendlyId::ActiveRecordAdapter::Relation
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -1,156 +1,162 @@
|
|
1
1
|
module FriendlyId
|
2
|
-
|
3
|
-
# The adapter for Ruby on Rails's ActiveRecord. Compatible with AR 2.2.x -
|
4
|
-
# 2.3.x.
|
5
2
|
module ActiveRecordAdapter
|
6
|
-
|
7
|
-
# The classes in this module are used internally by FriendlyId, and exist
|
8
|
-
# largely to avoid polluting the ActiveRecord models with too many
|
9
|
-
# FriendlyId-specific methods.
|
10
3
|
module Finders
|
11
4
|
|
12
|
-
|
13
|
-
# depending on the model_class's +friendly_id_config+ and the options
|
14
|
-
# passed into the constructor, it will decide whether to use simple or
|
15
|
-
# slugged finder, a single or multiple finder, and in the case of slugs,
|
16
|
-
# a cached or uncached finder.
|
17
|
-
class FinderProxy
|
5
|
+
class Find
|
18
6
|
|
19
7
|
extend Forwardable
|
8
|
+
def_delegators :@klass, :scoped, :friendly_id_config, :quoted_table_name, :table_name, :primary_key,
|
9
|
+
:connection, :name, :sanitize_sql
|
10
|
+
def_delegators :fc, :use_slugs?, :cache_column, :cache_column?
|
11
|
+
alias fc friendly_id_config
|
20
12
|
|
21
|
-
|
22
|
-
attr :
|
23
|
-
attr :ids
|
24
|
-
attr :model_class
|
13
|
+
attr :klass
|
14
|
+
attr :id
|
25
15
|
attr :options
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
@
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
def slugged_finder_class
|
67
|
-
multiple? ? multiple_slugged_finder_class : single_slugged_finder_class
|
68
|
-
end
|
69
|
-
|
70
|
-
def scoped?
|
71
|
-
!! options[:scope]
|
72
|
-
end
|
73
|
-
|
74
|
-
def single_slugged_finder_class
|
75
|
-
use_cache? ? SluggedModel::CachedSingleFinder : SluggedModel::SingleFinder
|
76
|
-
end
|
77
|
-
|
78
|
-
def use_cache?
|
79
|
-
cache_available? and !scoped?
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
83
|
-
|
84
|
-
# Wraps finds for multiple records using an array of friendly_ids.
|
85
|
-
# @abstract
|
86
|
-
module Multiple
|
87
|
-
|
88
|
-
include FriendlyId::Finders::Base
|
89
|
-
|
90
|
-
attr_reader :friendly_ids, :results, :unfriendly_ids
|
91
|
-
|
92
|
-
def initialize(ids, model_class, options={})
|
93
|
-
@friendly_ids, @unfriendly_ids = ids.partition {|id| FriendlyId::Finders::Base.friendly?(id) }
|
94
|
-
@unfriendly_ids = @unfriendly_ids.map {|id| id.class.respond_to?(:friendly_id_config) ? id.id : id}
|
95
|
-
super
|
16
|
+
attr :scope_val
|
17
|
+
attr :result
|
18
|
+
attr :friendly_ids
|
19
|
+
attr :unfriendly_ids
|
20
|
+
|
21
|
+
def initialize(klass, id, options)
|
22
|
+
@klass = klass
|
23
|
+
@id = id
|
24
|
+
@options = options
|
25
|
+
@scope_val = options.delete(:scope)
|
26
|
+
@scope_val = @scope_val.to_param if @scope_val && @scope_val.respond_to?(:to_param)
|
27
|
+
end
|
28
|
+
|
29
|
+
def find_one
|
30
|
+
return find_one_using_cached_slug if cache_column?
|
31
|
+
return find_one_using_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 => Slug.table_name.to_sym)
|
41
|
+
if fc.scope?
|
42
|
+
scope = scope.scoped(:conditions => {:slugs => {:scope => scope_val}})
|
43
|
+
end
|
44
|
+
end
|
45
|
+
@result = scope.all(options).uniq
|
46
|
+
validate_expected_size!
|
47
|
+
@result.each { |record| record.friendly_id_status.name = id }
|
48
|
+
end
|
49
|
+
|
50
|
+
def raise_error(error)
|
51
|
+
raise(error) unless fc.scope?
|
52
|
+
scope_message = scope_val || "expected, but none given"
|
53
|
+
message = "%s, scope: %s" % [error.message, scope_message]
|
54
|
+
raise ActiveRecord::RecordNotFound, message
|
96
55
|
end
|
97
56
|
|
98
57
|
private
|
99
58
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
59
|
+
def find_one_using_cached_slug
|
60
|
+
@result = scoped(:conditions => ["#{table_name}.#{cache_column} = ?", id]).first(options)
|
61
|
+
assign_status or find_one_using_slug
|
62
|
+
end
|
63
|
+
|
64
|
+
def find_one_using_slug
|
65
|
+
name, seq = id.to_s.parse_friendly_id
|
66
|
+
slugs = Slug.table_name.to_sym
|
67
|
+
scope = scoped(:conditions => {slugs => {:name => name, :sequence => seq}}, :joins => slugs)
|
68
|
+
scope = scope.scoped(:conditions => {slugs => {:scope => scope_val}}) if fc.scope?
|
69
|
+
@result = scope.first(options)
|
70
|
+
assign_status
|
71
|
+
end
|
72
|
+
|
73
|
+
def parse_ids!
|
74
|
+
@id = id.uniq.map do |member|
|
75
|
+
if member.respond_to?(:friendly_id_config)
|
76
|
+
member.id.to_i
|
77
|
+
else
|
78
|
+
member
|
79
|
+
end
|
80
|
+
end
|
81
|
+
@friendly_ids, @unfriendly_ids = @id.partition {|member| member.friendly_id?}
|
82
|
+
end
|
83
|
+
|
84
|
+
def validate_expected_size!
|
85
|
+
expected = expected_size
|
86
|
+
return if @result.size == expected
|
87
|
+
message = "Couldn't find all %s with IDs (%s) AND %s (found %d results, but was looking for %d)" % [
|
88
|
+
name.pluralize,
|
89
|
+
id.join(', '),
|
105
90
|
sanitize_sql(options[:conditions]),
|
106
|
-
|
107
|
-
|
91
|
+
result.size,
|
92
|
+
expected
|
108
93
|
]
|
94
|
+
raise ActiveRecord::RecordNotFound, message
|
109
95
|
end
|
110
96
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
def limit
|
118
|
-
options[:limit]
|
97
|
+
def assign_status
|
98
|
+
return unless @result
|
99
|
+
name, seq = @id.to_s.parse_friendly_id
|
100
|
+
@result.friendly_id_status.name = name
|
101
|
+
@result.friendly_id_status.sequence = seq if use_slugs?
|
102
|
+
@result
|
119
103
|
end
|
120
104
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
105
|
+
def expected_size
|
106
|
+
if options[:limit] && @id.size > options[:limit]
|
107
|
+
options[:limit]
|
108
|
+
else
|
109
|
+
@id.size
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def some_friendly_scope
|
114
|
+
query_slugs = use_slugs? && !cache_column?
|
115
|
+
pkey = "#{quoted_table_name}.#{primary_key}"
|
116
|
+
column = "#{table_name}.#{cache_column || fc.column}"
|
117
|
+
if @unfriendly_ids.present?
|
118
|
+
conditions = ["#{pkey} IN (?)", @unfriendly_ids]
|
119
|
+
if @friendly_ids.present?
|
120
|
+
if query_slugs
|
121
|
+
conditions[0] << " OR #{some_slugged_conditions}"
|
122
|
+
else
|
123
|
+
conditions[0] << " OR #{column} IN (?)"
|
124
|
+
conditions << @friendly_ids
|
125
|
+
end
|
126
|
+
end
|
127
|
+
elsif @friendly_ids.present?
|
128
|
+
conditions = query_slugs ? some_slugged_conditions : ["#{column} IN (?)", @friendly_ids]
|
129
|
+
end
|
130
|
+
scoped(:conditions => conditions)
|
131
|
+
end
|
132
|
+
|
133
|
+
def some_slugged_conditions
|
134
|
+
return unless @friendly_ids.present?
|
135
|
+
slug_table = Slug.quoted_table_name
|
136
|
+
fragment = "(#{slug_table}.name = %s AND #{slug_table}.sequence = %d)"
|
137
|
+
@friendly_ids.inject(nil) do |clause, id|
|
138
|
+
name, seq = id.parse_friendly_id
|
139
|
+
string = fragment % [connection.quote(name), seq]
|
140
|
+
clause ? clause + " OR #{string}" : string
|
141
|
+
end
|
134
142
|
end
|
135
|
-
|
136
143
|
end
|
137
144
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
def find(*args, &block)
|
145
|
-
finder = Finders::FinderProxy.new(self, *args, &block)
|
146
|
-
if finder.multiple?
|
147
|
-
finder.find
|
148
|
-
else
|
149
|
-
finder.unfriendly? ? super : finder.find or super
|
150
|
-
end
|
145
|
+
def find_one(id, options)
|
146
|
+
return super if id.blank? || id.unfriendly_id?
|
147
|
+
finder = Find.new(self, id, options)
|
148
|
+
finder.find_one or super
|
149
|
+
rescue ActiveRecord::RecordNotFound => error
|
150
|
+
finder.raise_error(error)
|
151
151
|
end
|
152
152
|
|
153
|
+
def find_some(ids, options)
|
154
|
+
return super if ids.empty?
|
155
|
+
finder = Find.new(self, ids, options)
|
156
|
+
finder.find_some
|
157
|
+
rescue ActiveRecord::RecordNotFound => error
|
158
|
+
finder.raise_error(error)
|
159
|
+
end
|
153
160
|
end
|
154
|
-
|
155
161
|
end
|
156
162
|
end
|