ismasan-sluggable_finder 2.0.4 → 2.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/sluggable_finder/finder.rb +26 -6
- data/lib/sluggable_finder/orm.rb +10 -13
- data/lib/sluggable_finder.rb +4 -3
- data/spec/sluggable_finder_spec.rb +23 -0
- metadata +1 -1
@@ -2,16 +2,36 @@ module SluggableFinder
|
|
2
2
|
# This module is included by the base class as well as AR asociation collections
|
3
3
|
#
|
4
4
|
module Finder
|
5
|
-
|
6
|
-
|
7
|
-
if (
|
8
|
-
options = {:conditions => ["#{
|
9
|
-
|
10
|
-
|
5
|
+
def find_sluggable(opts,*args)
|
6
|
+
key = args.first
|
7
|
+
if (key.is_a?(String) and !(key =~ /\A\d+\Z/))#only contain digits
|
8
|
+
options = {:conditions => ["#{ opts[:to]} = ?", key]}
|
9
|
+
error = "There is no #{opts[:sluggable_type]} with #{opts[:to]} '#{key}'"
|
10
|
+
with_scope(:find => options) do
|
11
|
+
find_without_slug(:first) or
|
12
|
+
raise SluggableFinder.not_found_exception.new(error)
|
13
|
+
end
|
11
14
|
else
|
12
15
|
find_without_slug(*args)
|
13
16
|
end
|
14
17
|
end
|
15
18
|
end
|
16
19
|
|
20
|
+
module BaseFinder
|
21
|
+
|
22
|
+
def find_with_slug(*args)
|
23
|
+
return find_without_slug(*args) unless respond_to?(:sluggable_finder_options)
|
24
|
+
options = sluggable_finder_options
|
25
|
+
find_sluggable(options,*args)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module AssociationProxyFinder
|
30
|
+
def find_with_slug(*args)
|
31
|
+
return find_without_slug(*args) unless @reflection.klass.respond_to?(:sluggable_finder_options)
|
32
|
+
options = @reflection.klass.sluggable_finder_options
|
33
|
+
find_sluggable(options,*args)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
17
37
|
end
|
data/lib/sluggable_finder/orm.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
module SluggableFinder
|
2
2
|
module Orm
|
3
3
|
|
4
|
-
def self.included(base)
|
5
|
-
base.extend ClassMethods
|
6
|
-
base.class_eval{include InstanceMethods}
|
7
|
-
class << base
|
8
|
-
alias_method_chain :find, :slug
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
4
|
module ClassMethods
|
13
5
|
|
14
6
|
def sluggable_finder(field = :title, options = {})
|
7
|
+
return if self.included_modules.include?(SluggableFinder::Orm::InstanceMethods)
|
8
|
+
extend SluggableFinder::Finder
|
9
|
+
extend SluggableFinder::BaseFinder
|
10
|
+
include SluggableFinder::Orm::InstanceMethods
|
11
|
+
|
12
|
+
class << self
|
13
|
+
alias_method_chain :find, :slug
|
14
|
+
end
|
15
|
+
|
15
16
|
write_inheritable_attribute(:sluggable_finder_options, {
|
16
17
|
:sluggable_type => ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s,
|
17
18
|
:from => field,
|
@@ -49,12 +50,8 @@ module SluggableFinder
|
|
49
50
|
"#{sluggable_finder_options[:to]}"
|
50
51
|
end
|
51
52
|
|
52
|
-
def the_scope
|
53
|
-
"#{sluggable_finder_options[:scope]}"
|
54
|
-
end
|
55
|
-
|
56
53
|
def to_param
|
57
|
-
|
54
|
+
self.#{sluggable_finder_options[:to]}
|
58
55
|
end
|
59
56
|
|
60
57
|
#{scope_condition_method}
|
data/lib/sluggable_finder.rb
CHANGED
@@ -2,7 +2,7 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|
2
2
|
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
3
|
|
4
4
|
module SluggableFinder
|
5
|
-
VERSION = '2.0.
|
5
|
+
VERSION = '2.0.5'
|
6
6
|
|
7
7
|
@@not_found_exception = nil
|
8
8
|
|
@@ -17,8 +17,7 @@ module SluggableFinder
|
|
17
17
|
class << self
|
18
18
|
|
19
19
|
def enable_activerecord
|
20
|
-
ActiveRecord::Base.extend SluggableFinder::
|
21
|
-
ActiveRecord::Base.class_eval{include SluggableFinder::Orm}
|
20
|
+
ActiveRecord::Base.extend SluggableFinder::Orm::ClassMethods
|
22
21
|
# support for associations
|
23
22
|
a = ActiveRecord::Associations
|
24
23
|
returning([ a::AssociationCollection ]) { |classes|
|
@@ -28,6 +27,8 @@ module SluggableFinder
|
|
28
27
|
end
|
29
28
|
}.each do |klass|
|
30
29
|
klass.send :include, SluggableFinder::Finder
|
30
|
+
klass.send :include, SluggableFinder::AssociationProxyFinder
|
31
|
+
klass.alias_method_chain :find, :slug
|
31
32
|
end
|
32
33
|
|
33
34
|
end
|
@@ -46,6 +46,7 @@ end
|
|
46
46
|
#
|
47
47
|
class Category < ActiveRecord::Base
|
48
48
|
has_many :scoped_items
|
49
|
+
has_many :simple_items
|
49
50
|
end
|
50
51
|
|
51
52
|
class ScopedItem < Item
|
@@ -158,6 +159,28 @@ describe PermalinkItem,'writing to custom field' do
|
|
158
159
|
end
|
159
160
|
end
|
160
161
|
|
162
|
+
describe SimpleItem,"scoping finder" do
|
163
|
+
before(:each) do
|
164
|
+
Item.delete_all
|
165
|
+
@category1 = Category.create!(:name => 'Category one')
|
166
|
+
@category2 = Category.create!(:name => 'Category two')
|
167
|
+
# Lets create 3 items with the same title, two of them in the same category
|
168
|
+
@item1 = @category1.simple_items.create!(:title => '1 in 1')
|
169
|
+
@item2 = @category1.simple_items.create!(:title => '2 in 1')
|
170
|
+
@item3 = @category2.simple_items.create!(:title => '1 in 2')
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should find in scope" do
|
174
|
+
@category1.simple_items.find('1-in-1').should == @item1
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should not find out of scope" do
|
178
|
+
lambda{
|
179
|
+
@category2.simple_items.find('1-in-1')
|
180
|
+
}.should raise_error(ActiveRecord::RecordNotFound)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
161
184
|
describe ScopedItem,'scoped to parent object' do
|
162
185
|
before(:each) do
|
163
186
|
Item.delete_all
|