friendly_id 3.0.6 → 3.1.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- 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
|