Skip to content

Commit

Permalink
Made slugged finders use cache first, if available.
Browse files Browse the repository at this point in the history
  • Loading branch information
norman committed Jan 27, 2010
1 parent e31c48c commit 3016c1a
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 27 deletions.
48 changes: 28 additions & 20 deletions extras/bench.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,53 @@

column :times
column :ar

report 'find model using id', (TIMES * FACTOR).ceil do
ar { User.find(id ||= get_id) }
ar { User.find(get_id) }
end

report 'find model using array of ids', (TIMES * FACTOR).ceil do
ar { User.find(ids ||= [get_id, get_id]) }
ar { User.find([get_id, get_id]) }
end

report 'find unslugged model using friendly id', (TIMES * FACTOR).ceil do
ar { User.find(id ||= USERS.rand) }
ar { User.find(USERS.rand) }
end

report 'find unslugged model using array of friendly ids', (TIMES * FACTOR).ceil do
ar { User.find(ids ||= [USERS.rand, USERS.rand]) }
ar { User.find([USERS.rand, USERS.rand]) }
end

report 'find slugged model using friendly id', (TIMES * FACTOR).ceil do
ar { Post.find(id ||= POSTS.rand) }
ar { Post.find(POSTS.rand) }
end

report 'find slugged model using array of friendly ids', (TIMES * FACTOR).ceil do
ar { Post.find(id ||= [POSTS.rand, POSTS.rand]) }
ar { Post.find([POSTS.rand, POSTS.rand]) }
end


report 'find cached slugged model using friendly id', (TIMES * FACTOR).ceil do
ar { District.find(DISTRICTS.rand) }
end

report 'find cached slugged model using array of friendly ids', (TIMES * FACTOR).ceil do
ar { District.find([DISTRICTS.rand, DISTRICTS.rand]) }
end

report 'find model using id, then to_param', (TIMES * FACTOR).ceil do
ar { User.find(id ||= get_id).to_param }
ar { User.find(get_id).to_param }
end
#
#
report 'find unslugged model using friendly id, then to_param', (TIMES * FACTOR).ceil do
ar { User.find(id ||= USERS.rand).to_param }
ar { User.find(USERS.rand).to_param }
end
#
#
report 'find slugged model using friendly id, then to_param', (TIMES * FACTOR).ceil do
ar { Post.find(id ||= POSTS.rand).to_param }
ar { Post.find(POSTS.rand).to_param }
end
#
#
report 'find cached slugged model using friendly id, then to_param', (TIMES * FACTOR).ceil do
ar { District.find(id ||= DISTRICTS.rand).to_param }
ar { District.find(DISTRICTS.rand).to_param }
end

summary 'Total'
Expand Down
31 changes: 27 additions & 4 deletions lib/friendly_id/active_record_2/slugged_model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ def unfriendly_ids?

end

class CachedMultipleFinder < SimpleModel::MultipleFinder
# The column used to store the cached slug.
def column
"#{table_name}.#{friendly_id_config.cache_column}"
end
end

class SingleFinder < Finders::SingleFinder

def find
Expand Down Expand Up @@ -129,19 +136,35 @@ def raise_scoped_error

end

class CachedSingleFinder < SimpleModel::SingleFinder

# The column used to store the cached slug.
def column
"#{table_name}.#{friendly_id_config.cache_column}"
end

def find_options
key = self.class.friendly?(id) ? column : model_class.primary_key
{:conditions => {key => id}}
end

end

# The methods in this module override ActiveRecord's +find_one+ and
# +find_some+ to add FriendlyId's features.
module FinderMethods

protected

def find_one(id_or_name, options)
finder = SingleFinder.new(id_or_name, self, options)
klass = friendly_id_config.cache_column ? CachedSingleFinder : SingleFinder
finder = klass.new(id_or_name, self, options)
finder.unfriendly? ? super : finder.find or super
end

def find_some(ids_and_names, options)
finder = MultipleFinder.new(ids_and_names, self, options).find
klass = friendly_id_config.cache_column ? CachedMultipleFinder : MultipleFinder
finder = klass.new(ids_and_names, self, options).find
end

# Since Rails goes out of its way to make these options completely
Expand Down Expand Up @@ -264,7 +287,7 @@ def to_param
def new_slug_needed?
!slug || slug_text_changed?
end

def scope_changed?
friendly_id_config.scope? && send(friendly_id_config.scope.to_param) != slug.scope
end
Expand Down Expand Up @@ -308,7 +331,7 @@ def set_slug_cache
send :update_without_callbacks
end
end

def update_scope
return unless scope_changed?
slug.update_attributes :scope => send(friendly_id_config.scope).to_param
Expand Down
4 changes: 2 additions & 2 deletions test/active_record_2/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def other_class
test "instances should have a friendly id" do
assert_match(/hello/, instance.friendly_id)
end

test "should return their friendly_id for #to_param" do
assert_match(instance.friendly_id, instance.to_param)
end
Expand Down Expand Up @@ -142,4 +142,4 @@ def other_class
end
end
end
end
end
2 changes: 1 addition & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
$VERBOSE = false

require 'rubygems'
require 'test/unit'
require 'test/unit'
require 'mocha'

# You can use "rake test AR_VERSION=2.2.3" to test against 2.2.3 for example.
Expand Down

0 comments on commit 3016c1a

Please sign in to comment.