find_by_param 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,57 +1,58 @@
1
1
  begin
2
- $KCODE = 'u'
3
2
  require 'rubygems'
4
3
  require 'active_support'
5
4
  rescue LoadError
6
5
  end
6
+
7
7
  module Railslove
8
8
  module Plugins
9
9
  module FindByParam
10
- def self.enable
10
+ def self.enable # :nodoc:
11
11
  return if ActiveRecord::Base.kind_of?(self::ClassMethods)
12
12
 
13
13
  ActiveRecord::Base.class_eval do
14
14
  class_inheritable_accessor :permalink_options
15
15
  self.permalink_options = {:param => :id}
16
-
16
+
17
17
  #default finders these are overwritten if you use make_permalink in
18
18
  # your model
19
- def self.find_by_param(value,args={})
19
+ def self.find_by_param(value,args={}) # :nodoc:
20
20
  find_by_id(value,args)
21
21
  end
22
- def self.find_by_param!(value,args={})
22
+ def self.find_by_param!(value,args={}) # :nodoc:
23
23
  find(value,args)
24
24
  end
25
25
  end
26
26
  ActiveRecord::Base.extend(self::ClassMethods)
27
27
  end
28
-
28
+
29
29
  module ClassMethods
30
-
31
-
30
+
31
+
32
32
  =begin rdoc
33
33
 
34
34
  This method initializes find_by_param
35
35
 
36
36
  class Post < ActiveRecord::Base
37
- make_permalink :with => :title, :prepend_id=>true
37
+ make_permalink :with => :title, :prepend_id => true
38
38
  end
39
39
 
40
- The only required parameter, is <tt>:with</tt>.
40
+ The only required parameter, is <tt>:with</tt>.
41
41
 
42
42
  If you want to use a non URL-save attribute as permalink your model should have a permalink-column to save the escaped permalink value. This field is then used for search.
43
43
 
44
- If your you can just say make_permalink :with => :login and you're done.
44
+ If your you can just say make_permalink :with => :login and you're done.
45
45
 
46
- You can use for example User.find_by_param(params[:id], args) to find the user by the defined permalink.
46
+ You can use for example User.find_by_param(params[:id], args) to find the user by the defined permalink.
47
47
 
48
48
  == Available options
49
49
 
50
50
  <tt>:with</tt>:: (required) The attribute that should be used as permalink
51
- <tt>:field</tt>:: The name of your permalink column. make_permalink first checks if there is a column.
52
- <tt>:prepend_id</tt>:: [true|false] Do you want to prepend the ID to the permalink? for URLs like: posts/123-my-post-title - find_by_param uses the ID column to search.
53
- <tt>:escape</tt>:: [true|false] Do you want to escape the permalink value? (strip chars like öä?&) - actually you must do that
54
- <tt>:validate</tt>:: [true|false] Don't validate the :with field - set this to false if you validate it on your own
51
+ <tt>:field</tt>:: The name of your permalink column. make_permalink first checks if there is a column, default is 'permalink'.
52
+ <tt>:prepend_id</tt>:: [true|false] Do you want to prepend the ID to the permalink? for URLs like: posts/123-my-post-title - find_by_param uses the ID column to search, default is false.
53
+ <tt>:param_size</tt>:: [Number] Desired maximum size of the permalink, default is 50.
54
+ <tt>:escape</tt>:: [true|false] Do you want to escape the permalink value? (strip chars like öä?&) - actually you must do that, default is true.
55
+ <tt>:validate</tt>:: [true|false] Don't validate the :with field - set this to false if you validate it on your own, default is true.
55
56
  <tt>:forbidden</tt>:: [Regexp|String|Array of Strings] Define which values should be forbidden. This is useful when combining user defined values to generate permalinks in combination with restful routing. <b>Make sure, especially in the case of a Regexp argument, that values may become valid by adding or incrementing a trailing integer.</b>
56
57
  =end
57
58
  def make_permalink(options={})
@@ -61,7 +62,7 @@ You can use for example User.find_by_param(params[:id], args) to find the user b
61
62
  options[:prepend_id] ||= false
62
63
  options[:param_size] ||= 50
63
64
  options[:validate] = true if options[:validate].nil?
64
-
65
+
65
66
  # validate if there is something we can use as param. you can overwrite the validate_param_is_not_blank method to customize the validation and the error messge.
66
67
  if !options[:prepend_id] || !options[:validate]
67
68
  validate :validate_param_is_not_blank
@@ -74,29 +75,29 @@ You can use for example User.find_by_param(params[:id], args) to find the user b
74
75
  options[:forbidden_strings] = Array(forbidden).map(&:to_s)
75
76
  end
76
77
  end
77
-
78
+
78
79
  if self.column_names.include?(options[:field].to_s)
79
80
  options[:param] = options[:field]
80
81
  before_save :save_permalink
81
82
  end
82
-
83
+
83
84
  self.permalink_options = options
84
- extend Railslove::Plugins::FindByParam::SingletonMethods
85
- include Railslove::Plugins::FindByParam::InstanceMethods
86
- rescue
87
- puts "[find_by_param error] database not available?"
85
+ extend Railslove::Plugins::FindByParam::SingletonMethods
86
+ include Railslove::Plugins::FindByParam::InstanceMethods
87
+ rescue ActiveRecord::ActiveRecordError
88
+ puts "[find_by_param error] database not available?"
88
89
  end
89
90
  end
90
-
91
+
91
92
  module SingletonMethods
92
-
93
+
93
94
  =begin rdoc
94
95
 
95
- Search for an object by the defined permalink column. Similar to find_by_login.
96
- Returns nil if nothing is found
97
- Accepts an options hash as a second parameter which is passed on to the rails finder.
96
+ Search for an object by the defined permalink column. Similar to
97
+ +find_by_login+. Returns +nil+ if nothing is found. Accepts an options hash as
98
+ second parameter which is passed on to the rails finder.
98
99
  =end
99
- def find_by_param(value,args={})
100
+ def find_by_param(value, args={})
100
101
  if permalink_options[:prepend_id]
101
102
  param = "id"
102
103
  value = value.to_i
@@ -108,9 +109,11 @@ Accepts an options hash as a second parameter which is passed on to the rails fi
108
109
 
109
110
  =begin rdoc
110
111
 
111
- Like find_by_param but raises an ActiveRecord::RecordNotFound error if nothing is found. Similar to find()
112
+ Like +find_by_param+ but raises an <tt>ActiveRecord::RecordNotFound</tt> error
113
+ if nothing is found - similar to find().
112
114
 
113
- Accepts an options hash as a second parameter which is passed on to the rails finder.
115
+ Accepts an options hash as second parameter which is passed on to the rails
116
+ finder.
114
117
  =end
115
118
  def find_by_param!(value, args={})
116
119
  param = permalink_options[:param]
@@ -119,25 +122,28 @@ Accepts an options hash as a second parameter which is passed on to the rails fi
119
122
  obj
120
123
  end
121
124
  end
122
-
125
+
123
126
  module InstanceMethods
124
127
  def to_param
125
128
  value = self.send(permalink_options[:param]).dup.to_s.downcase rescue ""
126
- returning "" do |param|
127
- param << "#{id}" if value.blank? || permalink_options[:prepend_id]
128
- param << "-" if permalink_options[:prepend_id]
129
- param << "#{escape_and_truncate_permalink(value)}"
129
+ ''.tap do |param|
130
+ if value.blank?
131
+ param << id.to_s
132
+ else
133
+ param << "#{id}-" if permalink_options[:prepend_id]
134
+ param << escape_and_truncate_permalink(value)
135
+ end
130
136
  end
131
137
  end
132
-
138
+
133
139
  protected
134
-
140
+
135
141
  def save_permalink
136
142
  return unless self.class.column_names.include?(permalink_options[:field].to_s)
137
143
  counter = 0
138
144
  base_value = escape_and_truncate_permalink(send(permalink_options[:with])).downcase
139
- permalink_value = "#{base_value}"
140
-
145
+ permalink_value = base_value.to_s
146
+
141
147
  conditions = ["#{self.class.table_name}.#{permalink_options[:field]} = ?", permalink_value]
142
148
  unless new_record?
143
149
  conditions.first << " and #{self.class.table_name}.#{self.class.primary_key} != ?"
@@ -145,17 +151,28 @@ Accepts an options hash as a second parameter which is passed on to the rails fi
145
151
  end
146
152
  while is_forbidden?(permalink_value) or
147
153
  self.class.count(:all, :conditions => conditions) > 0
148
- permalink_value = "#{base_value}-#{counter += 1}"
154
+ counter += 1
155
+ permalink_value = "#{base_value}-#{counter}"
156
+
157
+ if permalink_value.size > permalink_options[:param_size]
158
+ length = permalink_options[:param_size] - counter.to_s.size - 2
159
+ truncated_base = base_value[0..length]
160
+ permalink_value = "#{truncated_base}-#{counter}"
161
+ end
162
+
149
163
  conditions[1] = permalink_value
150
164
  end
151
165
  write_attribute(permalink_options[:field], permalink_value)
152
166
  true
153
167
  end
154
-
168
+
155
169
  def validate_param_is_not_blank
156
- errors.add(permalink_options[:with], "must have at least one non special character (a-z 0-9)") if self.escape_permalink( self.send(permalink_options[:with]) ).blank?
170
+ if self.escape_and_truncate_permalink(self.send(permalink_options[:with])).blank?
171
+ errors.add(permalink_options[:with],
172
+ "must have at least one non special character (a-z 0-9)")
173
+ end
157
174
  end
158
-
175
+
159
176
  def escape_permalink(value)
160
177
  value.to_s.parameterize
161
178
  end
@@ -166,7 +183,7 @@ Accepts an options hash as a second parameter which is passed on to the rails fi
166
183
  end
167
184
 
168
185
  def is_forbidden_string?(permalink_value)
169
- permalink_options[:forbidden_strings] &&
186
+ permalink_options[:forbidden_strings] &&
170
187
  permalink_options[:forbidden_strings].include?(permalink_value)
171
188
  end
172
189
 
@@ -175,14 +192,12 @@ Accepts an options hash as a second parameter which is passed on to the rails fi
175
192
  permalink_options[:forbidden_match] =~ permalink_value
176
193
  end
177
194
 
178
-
179
- #this escapes and truncates a value.
180
- #used to escape and truncate permalink value
181
195
  def escape_and_truncate_permalink(value)
182
- self.escape_permalink(value)[0...self.permalink_options[:param_size]]
196
+ p = self.escape_permalink(value)[0...self.permalink_options[:param_size]]
197
+ p.ends_with?('-') ? p.chop : p
183
198
  end
184
199
  end
185
-
200
+
186
201
  end
187
202
  end
188
203
  end
@@ -0,0 +1,7 @@
1
+ module Railslove
2
+ module Plugins
3
+ module FindByParam
4
+ VERSION = '0.2.0'
5
+ end
6
+ end
7
+ end
metadata CHANGED
@@ -1,121 +1,92 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: find_by_param
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
5
6
  platform: ruby
6
- authors:
7
+ authors:
7
8
  - Michael Bumann
8
9
  - Gregor Schmidt
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
-
13
- date: 2010-01-03 00:00:00 +01:00
14
- default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
13
+ date: 2011-09-05 00:00:00.000000000Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
17
16
  name: activerecord
17
+ requirement: &2157569500 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 3.0.3
18
23
  type: :runtime
19
- version_requirement:
20
- version_requirements: !ruby/object:Gem::Requirement
21
- requirements:
22
- - - ">="
23
- - !ruby/object:Gem::Version
24
- version: "2.3"
25
- version:
26
- - !ruby/object:Gem::Dependency
24
+ prerelease: false
25
+ version_requirements: *2157569500
26
+ - !ruby/object:Gem::Dependency
27
27
  name: activesupport
28
+ requirement: &2157568820 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 3.0.3
28
34
  type: :runtime
29
- version_requirement:
30
- version_requirements: !ruby/object:Gem::Requirement
31
- requirements:
32
- - - ">="
33
- - !ruby/object:Gem::Version
34
- version: "2.3"
35
- version:
36
- - !ruby/object:Gem::Dependency
35
+ prerelease: false
36
+ version_requirements: *2157568820
37
+ - !ruby/object:Gem::Dependency
37
38
  name: sqlite3-ruby
39
+ requirement: &2157568380 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
38
45
  type: :development
39
- version_requirement:
40
- version_requirements: !ruby/object:Gem::Requirement
41
- requirements:
42
- - - ">="
43
- - !ruby/object:Gem::Version
44
- version: "0"
45
- version:
46
- - !ruby/object:Gem::Dependency
47
- name: jeweler
48
- type: :development
49
- version_requirement:
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: 0.11.0
55
- version:
56
- - !ruby/object:Gem::Dependency
46
+ prerelease: false
47
+ version_requirements: *2157568380
48
+ - !ruby/object:Gem::Dependency
57
49
  name: rake
50
+ requirement: &2157567780 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
58
56
  type: :development
59
- version_requirement:
60
- version_requirements: !ruby/object:Gem::Requirement
61
- requirements:
62
- - - ">="
63
- - !ruby/object:Gem::Version
64
- version: "0"
65
- version:
66
- description: find_by_param is a nice and easy way to handle permalinks and dealing with searching for to_param values
57
+ prerelease: false
58
+ version_requirements: *2157567780
59
+ description: find_by_param is a nice and easy way to handle permalinks and dealing
60
+ with searching for to_param values
67
61
  email: michael@railslove.com
68
62
  executables: []
69
-
70
63
  extensions: []
71
-
72
- extra_rdoc_files:
73
- - README.md
74
- files:
75
- - .gitignore
76
- - MIT-LICENSE
77
- - README.md
78
- - Rakefile
79
- - init.rb
80
- - install.rb
64
+ extra_rdoc_files: []
65
+ files:
66
+ - lib/find_by_param/version.rb
81
67
  - lib/find_by_param.rb
82
- - shoulda_macros/find_by_param.rb
83
- - shoulda_macros/matchers.rb
84
- - tasks/find_by_param_tasks.rake
85
- - test/find_by_param_test.rb
86
- - test/schema.rb
87
- - test/test_helper.rb
88
- - uninstall.rb
89
- - version.yml
90
- has_rdoc: true
91
68
  homepage: http://github.com/bumi/find_by_param
92
69
  licenses: []
93
-
94
70
  post_install_message:
95
- rdoc_options:
96
- - --charset=UTF-8
97
- require_paths:
71
+ rdoc_options: []
72
+ require_paths:
98
73
  - lib
99
- required_ruby_version: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: "0"
104
- version:
105
- required_rubygems_version: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- version: "0"
110
- version:
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
111
86
  requirements: []
112
-
113
- rubyforge_project:
114
- rubygems_version: 1.3.5
87
+ rubyforge_project: ! '[none]'
88
+ rubygems_version: 1.8.5
115
89
  signing_key:
116
90
  specification_version: 3
117
91
  summary: Rails plugin to handle permalink values
118
- test_files:
119
- - test/find_by_param_test.rb
120
- - test/schema.rb
121
- - test/test_helper.rb
92
+ test_files: []
data/.gitignore DELETED
@@ -1,4 +0,0 @@
1
- doc
2
- README.html
3
- pkg
4
- find_by_param.gemspec
@@ -1,20 +0,0 @@
1
- Copyright (c) 2007 [Michael Bumann - Railslove.com]
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md DELETED
@@ -1,121 +0,0 @@
1
- find_by_param
2
- =============
3
-
4
- *find_by_param* helps you dealing with permalinks and finding objects by our
5
- permalink value
6
-
7
- class Post < ActiveRecord:Base
8
- make_permalink :with => :title
9
- end
10
-
11
- now you can do
12
-
13
- Post.find_by_param(...)
14
-
15
- If you have a permalink-column *find_by_param* saves the permalink there and
16
- uses that otherwise it just uses the provided attribute.
17
-
18
-
19
- Installation
20
- ========
21
-
22
- As gem from gemcutter:
23
- -------------
24
-
25
- % gem install find_by_param
26
-
27
- Building your own
28
- -------------
29
-
30
- % rake gemspec
31
- % rake install
32
-
33
- As Rails plugin
34
- -------------
35
-
36
- % script/plugin install git@github.com:bumi/find_by_param.git
37
-
38
-
39
- Examples
40
- ========
41
-
42
- Configuration
43
- -------------
44
-
45
- make_permalink :with => :login
46
- make_permalink :with => :title, :prepend_id => true
47
- make_permalink :with => :name, :forbidden => %w(new edit)
48
-
49
- Client code
50
- -----------
51
-
52
- Post.create(:title => "hey ho let's go!").to_param #=> "hey-ho-lets-go"
53
- # ... to_param is the method Rails calls to create the URL values
54
-
55
- Post.find_by_param("hey-ho-lets-go") #=> <Post>
56
-
57
- Post.find_by_param("is-not-there") #=> nil
58
- Post.find_by_param!("is-not-there") #=> raises ActiveRecord::RecordNotFound
59
-
60
-
61
- Basic Documentation
62
- ===================
63
-
64
- Options for make_permalink
65
- --------------------------
66
-
67
- The following options may be used, when configuring the permalink generation
68
- with `make_permalink`.
69
-
70
- * `:with` (required)
71
-
72
- The attribute that should be used as permalink
73
-
74
- * `:field`
75
-
76
- The name of your permalink column. make_permalink first checks if there is
77
- a column.
78
-
79
- * `:prepend_id => [true|false]`
80
-
81
- Do you want to prepend the ID to the permalink? for URLs like:
82
- `posts/123-my-post-title` - *find_by_param* uses the ID column to search.
83
-
84
- * `:escape => [true|false]`
85
-
86
- Do you want to escape the permalink value? (strip chars like `öä?&`) -
87
- actually you must do that
88
-
89
- * `:forbidden => [Regexp|String|Array of Strings]`
90
-
91
- Define which values should be forbidden. This is useful when combining user
92
- defined values to generate permalinks in combination with restful routing.
93
- **Make sure, especially in the case of a Regexp argument, that values may
94
- become valid by adding or incrementing a trailing integer.**
95
-
96
-
97
- Class methods provided by *find_by_param*
98
- ---------------------------------------
99
-
100
- The following methods are added as public methods to all classes containing a
101
- permalink field.
102
-
103
- * `find_by_param(id)`
104
-
105
- Look up a value by its permalink value, returns matching instance or
106
- `nil`, if none is found.
107
-
108
- * `find_by_param!(id)`
109
-
110
- Look up a value by its permalink value, returns matching instance or
111
- raises `ActiveRecord::RecordNotFound`, if none is found.
112
-
113
-
114
- Issues
115
- =======
116
-
117
- * Alex Sharp (http://github.com/ajsharp) pointed to an issue with STI. Better call make_permalink in every child class and not only in the parent class..
118
- * write nice docs
119
- * write nicer tests
120
-
121
- Copyright (c) 2007 \[Michael Bumann - Railslove.com\], released under the MIT license
data/Rakefile DELETED
@@ -1,45 +0,0 @@
1
- require 'rake'
2
- require 'rake/testtask'
3
- require 'rake/rdoctask'
4
-
5
- desc 'Default: run unit tests.'
6
- task :default => :test
7
-
8
- desc 'Test the find_by_param plugin.'
9
- Rake::TestTask.new(:test) do |t|
10
- t.libs << 'lib'
11
- t.pattern = 'test/**/*_test.rb'
12
- t.verbose = true
13
- end
14
-
15
- desc 'Generate documentation for the find_by_param plugin.'
16
- Rake::RDocTask.new(:rdoc) do |rdoc|
17
- rdoc.rdoc_dir = 'rdoc'
18
- rdoc.title = 'FindByParam'
19
- rdoc.options << '--line-numbers' << '--inline-source'
20
- rdoc.rdoc_files.include('README')
21
- rdoc.rdoc_files.include('lib/**/*.rb')
22
- end
23
-
24
- begin
25
- gem 'jeweler', '>= 0.11.0'
26
- require 'jeweler'
27
- Jeweler::Tasks.new do |s|
28
- s.name = "find_by_param"
29
- s.summary = "Rails plugin to handle permalink values"
30
- s.email = "michael@railslove.com"
31
- s.homepage = "http://github.com/bumi/find_by_param"
32
- s.description = "find_by_param is a nice and easy way to handle " +
33
- "permalinks and dealing with searching for to_param values"
34
- s.authors = ["Michael Bumann", "Gregor Schmidt"]
35
- s.add_dependency('activerecord', '>= 2.3')
36
- s.add_dependency('activesupport', '>= 2.3')
37
-
38
- s.add_development_dependency('sqlite3-ruby')
39
- s.add_development_dependency('jeweler', '>= 0.11.0')
40
- s.add_development_dependency('rake')
41
- end
42
- rescue LoadError
43
- puts "Jeweler not available. Install it with: sudo gem install jeweler --version '>= 0.11.0'"
44
- exit(1)
45
- end
data/init.rb DELETED
@@ -1 +0,0 @@
1
- require 'find_by_param'
data/install.rb DELETED
@@ -1 +0,0 @@
1
- puts IO.read(File.join(File.dirname(__FILE__), 'README'))
@@ -1,34 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'matchers')
2
- # this is experimental. My first try to write a shoulda matcher
3
- module Railslove
4
- module Plugins
5
- module FindByParam
6
- module Shoulda
7
- include Matchers
8
-
9
- def should_make_permalink(options = {})
10
- klass = self.name.gsub(/Test$/, '').constantize
11
-
12
- options[:field] ||= "permalink"
13
- options[:param] = options[:with]
14
- options[:escape] ||= true
15
- options[:prepend_id] ||= false
16
- options[:param_size] ||= 50
17
- options[:validate] ||= true
18
- if klass.column_names.include?(options[:field].to_s)
19
- options[:param] = options[:field]
20
- end
21
-
22
- matcher = validate_find_by_param_options(options)
23
-
24
- should matcher.description do
25
- assert_accepts(matcher, klass)
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
32
- class Test::Unit::TestCase
33
- extend Railslove::Plugins::FindByParam::Shoulda
34
- end
@@ -1,49 +0,0 @@
1
- # this nesting is actually a bit stupid :)
2
- module Railslove
3
- module Plugins
4
- module FindByParam
5
- module Shoulda
6
- module Matchers
7
- def validate_find_by_param_options(options)
8
- FindByParamMatcher.new(options)
9
- end
10
- class FindByParamMatcher
11
- def initialize(options)
12
- @expected_options = options
13
- end
14
-
15
- def matches?(klass)
16
- @klass = klass
17
- valid_permalink_options? && responds_to_find_by_param_class_methods? && responds_to_find_by_param_instance_methods?
18
- end
19
-
20
- def description
21
- "have valid find_by_pram_configuration"
22
- end
23
-
24
- def failure_message
25
- "invalid find_by_param configuration: expected: #{@expected_options.inspect} got: #{@klass.permalink_options.inspect}"
26
- end
27
-
28
- protected
29
- def valid_permalink_options?
30
- @expected_options == @klass.permalink_options
31
- end
32
-
33
- def responds_to_find_by_param_class_methods?
34
- %w{make_permalink find_by_param find_by_param!}.all? do |method|
35
- @klass.respond_to?(method)
36
- end
37
- end
38
-
39
- def responds_to_find_by_param_instance_methods?
40
- %w{escape_permalink}.all? do |method|
41
- @klass.new.respond_to?(method)
42
- end
43
- end
44
- end
45
- end
46
- end
47
- end
48
- end
49
- end
@@ -1,4 +0,0 @@
1
- # desc "Explaining what the task does"
2
- # task :find_by_param do
3
- # # Task goes here
4
- # end
@@ -1,156 +0,0 @@
1
- require(File.join(File.dirname(__FILE__), 'test_helper'))
2
-
3
- # TODO: make some nice mock objects!!!!!!!!!!!!!!!!!!
4
- class Post < ActiveRecord::Base; end
5
- class User < ActiveRecord::Base; end
6
- class Article < ActiveRecord::Base; end
7
- class Author < ActiveRecord::Base;
8
- def full_name
9
- [first_name, last_name].join(" ")
10
- end
11
- end
12
-
13
- # TODO DO BETTER TESTING!!!!
14
- class FindByParamTest < Test::Unit::TestCase
15
-
16
- def test_default_should_return_id
17
- post = Post.create(:title=>"hey ho let's go!")
18
- assert_equal post.to_param, post.id.to_s
19
- assert_equal post.permalink, nil
20
- end
21
-
22
- def test_permalink_should_be_saved
23
- Post.class_eval "make_permalink :with => :title"
24
- post = Post.create(:title=>"hey ho let's go!")
25
- assert_equal "hey-ho-let-s-go", post.to_param
26
- assert_equal post.permalink, post.to_param
27
- end
28
-
29
- def test_permalink_should_be_allowed_on_virtual_attributes
30
- Author.class_eval "make_permalink :with => :full_name"
31
- author = Author.create(:first_name => "Bugs", :last_name => "Bunny")
32
- assert_equal author.to_param, "bugs-bunny"
33
- assert_equal author.permalink, author.to_param
34
- end
35
-
36
- def test_permalink_should_not_create_forbidden_permalinks_given_one_string
37
- Author.class_eval "make_permalink :with => :first_name, :forbidden => 'me'"
38
- author = Author.create(:first_name => "me")
39
- assert_not_equal author.to_param, "me"
40
- end
41
-
42
- def test_permalink_should_not_create_forbidden_permalinks_given_mulitple_strings
43
- Author.class_eval "make_permalink :with => :first_name, :forbidden => %w{you me}"
44
- author1 = Author.create(:first_name => "me")
45
- author2 = Author.create(:first_name => "you")
46
-
47
- assert_not_equal author1.to_param, "me"
48
- assert_not_equal author2.to_param, "you"
49
- assert_not_equal author1.to_param, author2.to_param
50
- end
51
-
52
- def test_permalink_should_not_create_forbidden_permalinks_given_a_regexp
53
- Author.class_eval 'make_permalink :with => :first_name, :forbidden => /\D$/'
54
- author1 = Author.create(:first_name => "me")
55
- author2 = Author.create(:first_name => "you")
56
-
57
- assert_not_equal author1.to_param, "me"
58
- assert_not_equal author2.to_param, "you"
59
- assert_not_equal author1.to_param, author2.to_param
60
- end
61
-
62
- def test_permalink_should_be_trunkated
63
- Post.class_eval "make_permalink :with => :title"
64
- post = Post.create(:title=>"thisoneisaveryveryveryveryveryveryverylonglonglonglongtitlethisoneisaveryveryveryveryveryveryverylonglonglonglongtitle")
65
- assert_equal "thisoneisaveryveryveryveryveryveryverylonglonglong", post.to_param
66
- assert_equal post.to_param.size, 50
67
- assert_equal post.permalink, post.to_param
68
- end
69
-
70
- def test_permalink_should_be_trunkated_to_custom_size
71
- Post.class_eval "make_permalink :with => :title, :param_size=>10"
72
- post = Post.create(:title=>"thisoneisaveryveryveryveryveryveryverylonglonglonglongtitlethisoneisaveryveryveryveryveryveryverylonglonglonglongtitle")
73
- assert_equal "thisoneisa",post.to_param
74
- assert_equal post.permalink, post.to_param
75
- end
76
-
77
- def test_should_search_field_for_to_param_field
78
- User.class_eval "make_permalink :with => :login"
79
- user = User.create(:login=>"bumi")
80
- assert_equal user, User.find_by_param("bumi")
81
- assert_equal user, User.find_by_param!("bumi")
82
- end
83
-
84
- def test_should_validate_presence_of_the_field_used_to_create_the_param
85
- User.class_eval "make_permalink :with => :login"
86
- user = User.create(:login=>nil)
87
- assert_equal false, user.valid?
88
- end
89
-
90
- def test_to_param_should_perpend_id
91
- Article.class_eval "make_permalink :with => :title, :prepend_id=>true "
92
- article = Article.create(:title=>"hey ho let's go!")
93
- assert_equal article.to_param, "#{article.id}-hey-ho-let-s-go"
94
- end
95
-
96
- def test_should_increment_counter_if_not_unique
97
- Post.class_eval "make_permalink :with => :title"
98
- Post.create(:title=>"my awesome title!")
99
- post = Post.create(:title=>"my awesome title!")
100
- assert_equal "my-awesome-title-1", post.to_param
101
- assert_equal post.permalink, post.to_param
102
- end
103
-
104
- def test_should_record_not_found_error
105
- assert_raise(ActiveRecord::RecordNotFound) { Post.find_by_param!("isnothere") }
106
- end
107
- def test_should_return_nil_if_not_found
108
- assert_equal nil, Post.find_by_param("isnothere")
109
- end
110
-
111
- def test_should_strip_special_chars
112
- assert_equal "+-he-l-l-o-ni-ce-duaode", Post.new.send(:escape_permalink, "+*(he/=&l$l<o !ni^?ce-`duäöde;:@")
113
- end
114
-
115
- def test_does_not_leak_options
116
- Post.class_eval "make_permalink :with => :title, :forbidden => 'foo'"
117
- assert_equal( {:param => "permalink",
118
- :param_size => 50,
119
- :field => "permalink",
120
- :with => :title,
121
- :prepend_id => false,
122
- :escape => true,
123
- :validate => true,
124
- :forbidden_strings => ["foo"]}, Post.permalink_options)
125
-
126
- User.class_eval "make_permalink :with => :login, :forbidden => %w{foo bar}"
127
- assert_equal( {:param => :login,
128
- :param_size => 50,
129
- :field => "permalink",
130
- :with => :login,
131
- :prepend_id => false,
132
- :escape => true,
133
- :validate => true,
134
- :forbidden_strings => ["foo", "bar"]}, User.permalink_options)
135
-
136
- Article.class_eval "make_permalink :with => :title, :prepend_id => true, :forbidden => /baz$/"
137
- assert_equal( {:param => :title,
138
- :param_size => 50,
139
- :field => "permalink",
140
- :with => :title,
141
- :prepend_id => true,
142
- :escape => true,
143
- :validate => true,
144
- :forbidden_match => /baz$/}, Article.permalink_options)
145
-
146
- Author.class_eval "make_permalink :with => :full_name, :validate => false"
147
- assert_equal( {:param => "permalink",
148
- :param_size => 50,
149
- :field => "permalink",
150
- :with => :full_name,
151
- :prepend_id => false,
152
- :escape => true,
153
- :validate => false}, Author.permalink_options)
154
- end
155
-
156
- end
@@ -1,21 +0,0 @@
1
- ActiveRecord::Schema.define(:version => 0) do
2
-
3
- create_table :posts, :force => true do |t|
4
- t.string :title
5
- t.string :permalink
6
- end
7
-
8
- create_table :articles, :force => true do |t|
9
- t.string :title
10
- end
11
-
12
- create_table :users, :force => true do |t|
13
- t.string :login
14
- end
15
-
16
- create_table :authors, :force => true do |t|
17
- t.string :first_name
18
- t.string :last_name
19
- t.string :permalink
20
- end
21
- end
@@ -1,17 +0,0 @@
1
- require 'test/unit'
2
- require 'rubygems'
3
- require 'active_record'
4
- require 'active_support'
5
- #require 'active_support/multibyte'
6
- require 'find_by_param'
7
- class ActiveRecord::Base
8
- class_inheritable_accessor :permalink_options
9
- self.permalink_options = {:param => :id}
10
- end
11
- ActiveRecord::Base.send(:include, Railslove::Plugins::FindByParam)
12
-
13
- ActiveRecord::Base.establish_connection({
14
- 'adapter' => 'sqlite3',
15
- 'database' => ':memory:'
16
- })
17
- load(File.join(File.dirname(__FILE__), 'schema.rb'))
@@ -1 +0,0 @@
1
- # Uninstall hook code here
@@ -1,4 +0,0 @@
1
- ---
2
- :major: 0
3
- :minor: 1
4
- :patch: 0