slugable 0.0.4 → 1.0.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2b0a37a9a60ba3abef0792c337b76720cefc99ef
4
+ data.tar.gz: 8c892a3ce4d03dd42cf890d9c122a791e937d690
5
+ SHA512:
6
+ metadata.gz: 52a1957403eebed9c904e51d9b36b93ed7d5e7e49f0a1b4537ebcb3cf1ee6de480557f57a0f7d6cd3f7c2986c0d86cd4b1a714bfc04a6e67c81aeb6293c818ab
7
+ data.tar.gz: c4b5b0fe345489617eb9160867122e288b467a707e2b7d2adaf4dcb6b4cd6935f7e9ffd88120ef145b7dae7b1b4433cfd81f6b3a83906937ad63fe1bc0c55454
data/.gitignore CHANGED
@@ -3,7 +3,6 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
- Gemfile.lock
7
6
  InstalledFiles
8
7
  _yardoc
9
8
  coverage
@@ -16,3 +15,5 @@ test/tmp
16
15
  test/version_tmp
17
16
  tmp
18
17
  .idea/
18
+ Gemfile.lock
19
+ gemfiles/*.lock
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use ruby-2.2.2@slugable --create
@@ -0,0 +1,26 @@
1
+ cache: bundler
2
+ language: ruby
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.2.2
6
+ before_install:
7
+ - rm .rvmrc
8
+ script:
9
+ - "bundle exec rspec spec/"
10
+ sudo: false
11
+ gemfile:
12
+ - gemfiles/activerecord_3.2.gemfile
13
+ - gemfiles/activerecord_4.0.gemfile
14
+ - gemfiles/activerecord_4.1.gemfile
15
+ - gemfiles/activerecord_4.2.gemfile
16
+ matrix:
17
+ exclude:
18
+ - rvm: 1.9.3
19
+ gemfile: gemfiles/activerecord_4.0.gemfile
20
+ - rvm: 1.9.3
21
+ gemfile: gemfiles/activerecord_4.1.gemfile
22
+ - rvm: 1.9.3
23
+ gemfile: gemfiles/activerecord_4.2.gemfile
24
+ addons:
25
+ code_climate:
26
+ repo_token: 3e779acb537014cbfd1a7c48c7a509d3197afe962cd1738e832a46b439919e24
@@ -0,0 +1,24 @@
1
+ # Appraisals
2
+ appraise "activerecord-3.2" do
3
+ gem "activerecord", "~> 3.2.1"
4
+ gem "ancestry", "~> 1.3.0"
5
+
6
+ gem "test-unit", "~> 3.0"
7
+ end
8
+
9
+ if RUBY_VERSION > "1.9.3"
10
+ appraise "activerecord-4.0" do
11
+ gem "activerecord", "~> 4.0.1"
12
+ gem "ancestry", "~> 2.1.0"
13
+ end
14
+
15
+ appraise "activerecord-4.1" do
16
+ gem "activerecord", "~> 4.1.1"
17
+ gem "ancestry", "~> 2.1.0"
18
+ end
19
+
20
+ appraise "activerecord-4.2" do
21
+ gem "activerecord", "~> 4.2.1"
22
+ gem "ancestry", "~> 2.1.0"
23
+ end
24
+ end
data/README.md CHANGED
@@ -1,15 +1,39 @@
1
1
  # Slugable
2
2
 
3
- * adds support for seo friendly url
4
- * one helper method has_slug
5
- * support for ancestry models 'https://github.com/stefankroes/ancestry'
6
- * be default cache ancestry models url, can be changed
3
+ [![Build Status](https://travis-ci.org/mirrec/slugable.svg?branch=master)](https://travis-ci.org/mirrec/slugable)
4
+ [![Gem Version](https://badge.fury.io/rb/slugable.svg)](https://badge.fury.io/rb/slugable)
5
+ [![Code Climate](https://codeclimate.com/github/mirrec/slugable/badges/gpa.svg)](https://codeclimate.com/github/mirrec/slugable)
6
+ [![Test Coverage](https://codeclimate.com/github/mirrec/slugable/badges/coverage.svg)](https://codeclimate.com/github/mirrec/slugable/coverage)
7
+
8
+ * adds support for creating seo friendly url to your active record models and simplifies generating url
9
+ * gem is tests against rails 3.2, 4.0, 4.1, 4.2 and ruby 1.9.3. and 2.2.2
10
+
11
+ ```ruby
12
+ # model
13
+ class Article < ActiveRecord::Base
14
+ # has columns: id, name, slug
15
+ has_slug
16
+ end
17
+
18
+ # creating new
19
+ item = Article.create!(name: 'First article')
20
+ item.slug # => 'first-article'
21
+ item.to_slug # => 'first-article'
22
+
23
+ # routes to the article
24
+ get "articles/:slug" => "articles#show", as: :article
25
+
26
+ # view
27
+ link_to 'My first article', article_path(item.to_slug) # => '/articles/first-article'
28
+ ```
7
29
 
8
30
  ## Installation
9
31
 
10
32
  Add this line to your application's Gemfile:
11
33
 
12
- gem 'slugable'
34
+ ```ruby
35
+ gem 'slugable'
36
+ ```
13
37
 
14
38
  And then execute:
15
39
 
@@ -21,91 +45,139 @@ Or install it yourself as:
21
45
 
22
46
  ## Usage
23
47
 
24
- in model use method has_slug
48
+ * default configuration converts name column to slug column and formatted by parameterize method from active support
49
+ * it internally use callbacks to do the job
50
+ * it also adds several convenient methods for generating url parts `to_slug`, `to_slug_was`, `to_slug_will`
25
51
 
26
- class Item < ActiveRecord::Base
27
- attr_accessor :name, :slug
52
+ ```ruby
53
+ class Item < ActiveRecord::Base
54
+ # columns :name, :slug
28
55
 
29
- has_slug # default :from => :name, :to => :slug, :formatter => :parameterize, :cache_tree => true
30
- end
56
+ has_slug # default from: :name, to: :slug
57
+ end
31
58
 
32
- # then in code
33
- item = Item.create!(:name => "my name is")
34
- item.slug # => "my-name-is"
59
+ # then in code
60
+ item = Item.create!(name: "my name is")
61
+ item.slug # => "my-name-is"
35
62
 
36
- item.to_slug # => "my-name-is"
63
+ item.to_slug # => "my-name-is"
37
64
 
38
- item.slug = "new-slug
65
+ item.slug = "new-slug"
39
66
 
40
- item.to_slug_was # => "my-name-is"
41
- item.to_slug_will # => "new-slug"
42
- item.to_slug # => "new-slug"
67
+ item.to_slug_was # => "my-name-is"
68
+ item.to_slug_will # => "new-slug"
69
+ item.to_slug # => "new-slug"
70
+ ```
43
71
 
44
72
  you can override defaults by passing hash
45
73
 
74
+ ```ruby
75
+ class Page < ActiveRecord::Base
76
+ # has columns: :id, :title, :seo_url
46
77
 
47
- class Page < ActiveRecord::Base
48
- attr_accessor :title, :seo_url
49
-
50
- has_slug :from => :title, :to => :seo_url, :formatter => :my_style
51
- end
52
-
53
- class String
54
- def my_style
55
- self.parameterize
56
- end
57
- end
58
-
59
- # then in code
60
- page = Page.create!(:title => "my name is", :seo_url => "my url")
61
- page.seo_url # => "my-url"
62
- page.to_seo_url # => "my-url"
63
-
64
- if you have model with ancestry gem 'https://github.com/stefankroes/ancestry'
65
-
66
-
67
- class Category < ActiveRecord::Base
68
- attr_accessor :name, :slug
69
-
70
- has_ancestry
71
- has_slug
72
- end
73
-
74
- # then in code
75
- root = Category.create!(:name => "root", :slug => "root")
76
- root.slug # => "root"
77
- root.to_slug # => ["root"]
78
-
79
- child = Category.new(:name => "child", :slug => "child")
80
- child.parent = root
81
- child.save!
82
-
83
- child.slug # => "child"
84
- child.to_slug # => ["root", "child"]
85
-
86
- branch = Category.create!(:name => "branch", :slug => "branch")
87
- child.parent = branch
88
- child.slug = "renamed"
89
-
90
- child.to_slug_was # => ["root", "child"]
91
- child.to_slug_will # => ["branch", "renamed"]
92
-
93
- child.to_slug # => ["root", "child"]
94
- child.save!
95
- child.to_slug # => ["branch", "renamed"]
96
-
97
- ## configuration
98
-
99
- By default all ancestry structure are cached to prevent useless calls to fetch same record from database just for slug values.
100
- You can pass :cache_tree option to disable it like this.
101
-
102
-
103
- class Category < ActiveRecord::Base
104
- attr_accessor :name, :slug
105
-
106
- has_ancestry
107
- has_slug :cache_tree => false
108
- end
78
+ has_slug from: :title, to: :seo_url, formatter: lambda { |string| string.downcase }
79
+ end
80
+
81
+ # then in code
82
+ page = Page.create!(title: "NAME")
83
+ page.seo_url # => "name"
84
+ page.to_seo_url # => "name"
85
+ ```
86
+
87
+ if model is a tree structure and you use [ancestry gem](https://github.com/stefankroes/ancestry),
88
+ tree like structure will be generated
89
+
90
+ ```ruby
91
+ class Category < ActiveRecord::Base
92
+ # has columns: :id, :name, :slug
93
+
94
+ has_ancestry
95
+ has_slug
96
+ end
97
+
98
+ # then in code
99
+ root = Category.create!(name: "root", slug: "root")
100
+ root.slug # => "root"
101
+ root.to_slug # => ["root"]
102
+
103
+ child = Category.new(name: "child", slug: "child")
104
+ child.parent = root
105
+ child.save!
106
+
107
+ child.slug # => "child"
108
+ child.to_slug # => ["root", "child"]
109
+
110
+ branch = Category.create!(name: "branch", slug: "branch")
111
+ child.parent = branch
112
+ child.slug = "renamed"
113
+
114
+ child.to_slug_was # => ["root", "child"]
115
+ child.to_slug_will # => ["branch", "renamed"]
116
+
117
+ child.to_slug # => ["root", "child"]
118
+ child.save!
119
+ child.to_slug # => ["branch", "renamed"]
120
+ ```
121
+
122
+ * You can cache slug for tree structure if you want to optimize performance, all you need is to pass cache storage object
123
+
124
+ ```ruby
125
+ class Category < ActiveRecord::Base
126
+ # has columns: :id, :name, :slug
127
+
128
+ has_ancestry
129
+ has_slug tree_cache_storage: Rails.cache
130
+ end
131
+ ```
132
+
133
+ ## Configuration
134
+
135
+ You can set up default formatter and default tree_cache_storage in you initializer.
136
+
137
+ ```ruby
138
+ class MyFormatter
139
+ def self.call(string)
140
+ string.my_own_parameterize
141
+ end
142
+ end
143
+
144
+ Slugable.configure do |config|
145
+ config.formatter = MyFormatter
146
+ config.tree_cache_storage = Rails.cache
147
+ end
148
+ ```
149
+
150
+ `to_slug`, `to_slug_was` and `to_slug_will` methods are implemented by to_slug_builder. You can implement you own one and pass as configuration
151
+
152
+ ```ruby
153
+ # you own to slug builder
154
+ class StupidToSlug
155
+ def to_slug(record)
156
+ "to_slug_#{record.id}"
157
+ end
158
+
159
+ def to_slug_was(record)
160
+ "to_slug_was_#{record.id}"
161
+ end
162
+
163
+ def to_slug_will(record)
164
+ "to_slug_will_#{record.id}"
165
+ end
166
+ end
167
+
168
+ # model
169
+ class News < ActiveRecord::Base
170
+ # columns: :id, :name, :slug
171
+
172
+ has_slug to_slug_builder: StupidToSlug.new
173
+ end
174
+
175
+ # code
176
+ news = News.create!(name: 'whatever')
177
+ news.to_slug # => "to_slug_#{news.id}"
178
+ news.to_slug_was # => "to_slug_was_#{news.id}"
179
+ news.to_slug_will # => "to_slug_will_#{news.id}"
180
+ ```
109
181
 
110
182
  ## Contributing
111
183
 
data/Rakefile CHANGED
@@ -1 +1,14 @@
1
- require "bundler/gem_tasks"
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ require 'rake'
6
+ require 'rspec/core/rake_task'
7
+
8
+ Bundler::GemHelper.install_tasks
9
+
10
+ begin
11
+ RSpec::Core::RakeTask.new(:spec)
12
+ task :default => :spec
13
+ rescue LoadError
14
+ end
@@ -1,3 +1,53 @@
1
+ # 1.0.0 (November 22, 2015)
2
+ ## added
3
+ * add ability to pass cache storage to tree structure `tree_cache_storage`
4
+ * add ability to set default `formatter` and `tree_cache_storage` in config
5
+ ```ruby
6
+ Slugable.configure do |config|
7
+ config.formatter = MyFormatter
8
+ config.tree_cache_storage = Rails.cache
9
+ end
10
+ ```
11
+ * introduce slug builder
12
+ * add ability to pass own slug builder
13
+ ```ruby
14
+ # you own to slug builder
15
+ class StupidToSlug
16
+ def to_slug(record)
17
+ "to_slug_#{record.id}"
18
+ end
19
+
20
+ def to_slug_was(record)
21
+ "to_slug_was_#{record.id}"
22
+ end
23
+
24
+ def to_slug_will(record)
25
+ "to_slug_will_#{record.id}"
26
+ end
27
+ end
28
+
29
+ # model
30
+ class News < ActiveRecord::Base
31
+ # columns: :id, :name, :slug
32
+
33
+ has_slug to_slug_builder: StupidToSlug.new
34
+ end
35
+ ```
36
+ * travis ci for running tests
37
+ * tests run against ruby `1.9.3`, `2.2.2` and `activerecord` from >= `3.2` <= `4.2`
38
+ * test coverage
39
+ * code climate
40
+ ## changed
41
+ * big internal refactoring
42
+ * `formatter` param now expect callable object
43
+ * `cache_tree` option has been change to `tree_cache_storage` and expect object that can store cache (e.g. Rails.cache), it is `nil` by default
44
+ * ruby version to `2.2.2`
45
+ * hash to new syntax
46
+ * all spec uses expect syntax
47
+ * `to_slug` method for tree structure now returns array all the time
48
+ ## fixed
49
+ * several bugs with caching
50
+
1
51
  # 0.0.4 (May 30, 2013)
2
52
  ## fixed
3
53
  * `to_slug` method not skip nil in path
@@ -1,40 +1,47 @@
1
1
  ActiveRecord::Schema.define do
2
- create_table "items", :force => true do |t|
2
+ create_table "flat_items", force: true do |t|
3
3
  t.string "name"
4
4
  t.string "title"
5
5
  t.string "slug"
6
6
  t.string "seo_url"
7
- t.datetime "created_at", :null => false
8
- t.datetime "updated_at", :null => false
7
+ t.datetime "created_at", null: false
8
+ t.datetime "updated_at", null: false
9
9
  end
10
10
 
11
- create_table "pages", :force => true do |t|
11
+ create_table "flat_pages", force: true do |t|
12
12
  t.string "title"
13
13
  t.string "seo_url"
14
- t.datetime "created_at", :null => false
15
- t.datetime "updated_at", :null => false
14
+ t.datetime "created_at", null: false
15
+ t.datetime "updated_at", null: false
16
16
  end
17
17
 
18
- create_table "categories", :force => true do |t|
18
+ create_table "tree_categories", force: true do |t|
19
19
  t.string "name"
20
20
  t.string "ancestry"
21
21
  t.string "slug"
22
- t.datetime "created_at", :null => false
23
- t.datetime "updated_at", :null => false
22
+ t.datetime "created_at", null: false
23
+ t.datetime "updated_at", null: false
24
24
  end
25
25
 
26
- create_table "products", :force => true do |t|
26
+ create_table "flat_products", force: true do |t|
27
27
  t.string "name"
28
28
  t.string "slug"
29
- t.datetime "created_at", :null => false
30
- t.datetime "updated_at", :null => false
29
+ t.datetime "created_at", null: false
30
+ t.datetime "updated_at", null: false
31
31
  end
32
32
 
33
- create_table "tree_items", :force => true do |t|
33
+ create_table "tree_items", force: true do |t|
34
34
  t.string "name"
35
35
  t.string "ancestry"
36
36
  t.string "slug"
37
- t.datetime "created_at", :null => false
38
- t.datetime "updated_at", :null => false
37
+ t.datetime "created_at", null: false
38
+ t.datetime "updated_at", null: false
39
+ end
40
+
41
+ create_table "flat_news", force: true do |t|
42
+ t.string "name"
43
+ t.string "slug"
44
+ t.datetime "created_at", null: false
45
+ t.datetime "updated_at", null: false
39
46
  end
40
47
  end