friendly_id 3.3.3.0 → 4.0.0.beta7
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.
- data/.gitignore +11 -0
- data/.travis.yml +24 -0
- data/.yardopts +4 -0
- data/Changelog.md +9 -10
- data/README.md +39 -48
- data/Rakefile +56 -58
- data/WhatsNew.md +95 -0
- data/bench.rb +63 -0
- data/friendly_id.gemspec +40 -0
- data/gemfiles/Gemfile.rails-3.0.rb +18 -0
- data/gemfiles/Gemfile.rails-3.0.rb.lock +52 -0
- data/gemfiles/Gemfile.rails-3.1.rb +18 -0
- data/gemfiles/Gemfile.rails-3.1.rb.lock +57 -0
- data/lib/friendly_id.rb +126 -80
- data/lib/friendly_id/active_record_adapter/relation.rb +10 -2
- data/lib/friendly_id/active_record_adapter/slugged_model.rb +3 -9
- data/lib/friendly_id/base.rb +132 -0
- data/lib/friendly_id/configuration.rb +65 -152
- data/lib/friendly_id/finder_methods.rb +20 -0
- data/lib/friendly_id/history.rb +88 -0
- data/lib/friendly_id/migration.rb +18 -0
- data/lib/friendly_id/model.rb +22 -0
- data/lib/friendly_id/object_utils.rb +40 -0
- data/lib/friendly_id/reserved.rb +46 -0
- data/lib/friendly_id/scoped.rb +131 -0
- data/lib/friendly_id/slug.rb +9 -0
- data/lib/friendly_id/slug_sequencer.rb +82 -0
- data/lib/friendly_id/slugged.rb +191 -76
- data/lib/friendly_id/version.rb +2 -2
- data/test/base_test.rb +54 -0
- data/test/configuration_test.rb +27 -0
- data/test/core_test.rb +30 -0
- data/test/databases.yml +19 -0
- data/test/helper.rb +88 -0
- data/test/history_test.rb +55 -0
- data/test/object_utils_test.rb +26 -0
- data/test/reserved_test.rb +26 -0
- data/test/schema.rb +59 -0
- data/test/scoped_test.rb +57 -0
- data/test/shared.rb +118 -0
- data/test/slugged_test.rb +83 -0
- data/test/sti_test.rb +48 -0
- metadata +110 -102
- data/Contributors.md +0 -46
- data/Guide.md +0 -626
- data/extras/README.txt +0 -3
- data/extras/bench.rb +0 -40
- data/extras/extras.rb +0 -38
- data/extras/prof.rb +0 -19
- data/extras/template-gem.rb +0 -26
- data/extras/template-plugin.rb +0 -28
- data/generators/friendly_id/friendly_id_generator.rb +0 -30
- data/generators/friendly_id/templates/create_slugs.rb +0 -18
- data/lib/tasks/friendly_id.rake +0 -19
- data/rails/init.rb +0 -2
- data/test/active_record_adapter/ar_test_helper.rb +0 -149
- data/test/active_record_adapter/basic_slugged_model_test.rb +0 -14
- data/test/active_record_adapter/cached_slug_test.rb +0 -76
- data/test/active_record_adapter/core.rb +0 -138
- data/test/active_record_adapter/custom_normalizer_test.rb +0 -20
- data/test/active_record_adapter/custom_table_name_test.rb +0 -22
- data/test/active_record_adapter/default_scope_test.rb +0 -30
- data/test/active_record_adapter/optimistic_locking_test.rb +0 -18
- data/test/active_record_adapter/scoped_model_test.rb +0 -129
- data/test/active_record_adapter/simple_test.rb +0 -76
- data/test/active_record_adapter/slug_test.rb +0 -34
- data/test/active_record_adapter/slugged.rb +0 -33
- data/test/active_record_adapter/slugged_status_test.rb +0 -28
- data/test/active_record_adapter/sti_test.rb +0 -22
- data/test/active_record_adapter/support/database.jdbcsqlite3.yml +0 -2
- data/test/active_record_adapter/support/database.mysql.yml +0 -4
- data/test/active_record_adapter/support/database.mysql2.yml +0 -4
- data/test/active_record_adapter/support/database.postgres.yml +0 -6
- data/test/active_record_adapter/support/database.sqlite3.yml +0 -2
- data/test/active_record_adapter/support/models.rb +0 -104
- data/test/active_record_adapter/tasks_test.rb +0 -82
- data/test/compatibility/ancestry/Gemfile.lock +0 -34
- data/test/friendly_id_test.rb +0 -96
- data/test/test_helper.rb +0 -13
data/lib/friendly_id/slugged.rb
CHANGED
@@ -1,105 +1,220 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
require "friendly_id/slug_sequencer"
|
3
3
|
|
4
|
-
|
4
|
+
module FriendlyId
|
5
|
+
=begin
|
6
|
+
This module adds in-table slugs to a model.
|
7
|
+
|
8
|
+
Slugs are unique id strings that have been processed to remove or replace
|
9
|
+
characters that a developer considers inconvenient for use in URLs. For example,
|
10
|
+
blog applications typically use a post title to provide the basis of a search
|
11
|
+
engine friendly URL:
|
12
|
+
|
13
|
+
"Gone With The Wind" -> "gone-with-the-wind"
|
14
|
+
|
15
|
+
FriendlyId generates slugs from a method or column that you specify, and stores
|
16
|
+
them in a field in your model. By default, this field must be named +:slug+,
|
17
|
+
though you may change this using the
|
18
|
+
{FriendlyId::Slugged::Configuration#slug_column slug_column} configuration
|
19
|
+
option. You should add an index to this field. You may also wish to constrain it
|
20
|
+
to NOT NULL, but this depends on your app's behavior and requirements.
|
21
|
+
|
22
|
+
=== Example Setup
|
23
|
+
|
24
|
+
# your model
|
25
|
+
class Post < ActiveRecord::Base
|
26
|
+
extend FriendlyId
|
27
|
+
friendly_id :title, :use => :slugged
|
28
|
+
validates_presence_of :title, :slug, :body
|
29
|
+
end
|
5
30
|
|
6
|
-
|
31
|
+
# a migration
|
32
|
+
class CreatePosts < ActiveRecord::Migration
|
33
|
+
def self.up
|
34
|
+
create_table :posts do |t|
|
35
|
+
t.string :title, :null => false
|
36
|
+
t.string :slug, :null => false
|
37
|
+
t.text :body
|
38
|
+
end
|
7
39
|
|
8
|
-
|
9
|
-
# numeric, but the model has no slug, or +id+ is friendly and current
|
10
|
-
def best?
|
11
|
-
current? || (numeric? && !record.slug)
|
40
|
+
add_index :posts, :slug, :unique => true
|
12
41
|
end
|
13
42
|
|
14
|
-
|
15
|
-
|
16
|
-
!! slug && slug.current?
|
43
|
+
def self.down
|
44
|
+
drop_table :posts
|
17
45
|
end
|
46
|
+
end
|
18
47
|
|
19
|
-
|
20
|
-
def friendly?
|
21
|
-
!! (name or slug)
|
22
|
-
end
|
48
|
+
=== Slug Format
|
23
49
|
|
24
|
-
|
25
|
-
|
26
|
-
|
50
|
+
By default, FriendlyId uses Active Support's
|
51
|
+
paramaterize[http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize]
|
52
|
+
method to create slugs. This method will intelligently replace spaces with
|
53
|
+
dashes, and Unicode Latin characters with ASCII approximations:
|
27
54
|
|
28
|
-
|
29
|
-
|
30
|
-
!current?
|
31
|
-
end
|
55
|
+
movie = Movie.create! :title => "Der Preis fürs Überleben"
|
56
|
+
movie.slug #=> "der-preis-furs-uberleben"
|
32
57
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
58
|
+
==== Slug Uniqueness
|
59
|
+
|
60
|
+
When you try to insert a record that would generate a duplicate friendly id,
|
61
|
+
FriendlyId will append a sequence to the generated slug to ensure uniqueness:
|
62
|
+
|
63
|
+
car = Car.create :title => "Peugot 206"
|
64
|
+
car2 = Car.create :title => "Peugot 206"
|
65
|
+
|
66
|
+
car.friendly_id #=> "peugot-206"
|
67
|
+
car2.friendly_id #=> "peugot-206--2"
|
68
|
+
|
69
|
+
==== Changing the Slug Sequence Separator
|
70
|
+
|
71
|
+
You can do this with the {Slugged::Configuration#sequence_separator
|
72
|
+
sequence_separator} configuration option.
|
73
|
+
|
74
|
+
==== Column or Method?
|
75
|
+
|
76
|
+
FriendlyId always uses a method as the basis of the slug text - not a column. It
|
77
|
+
first glance, this may sound confusing, but remember that Active Record provides
|
78
|
+
methods for each column in a model's associated table, and that's what
|
79
|
+
FriendlyId uses.
|
80
|
+
|
81
|
+
Here's an example of a class that uses a custom method to generate the slug:
|
37
82
|
|
83
|
+
class Person < ActiveRecord::Base
|
84
|
+
friendly_id :name_and_location
|
85
|
+
def name_and_location
|
86
|
+
"#{name} from #{location}"
|
38
87
|
end
|
88
|
+
end
|
39
89
|
|
40
|
-
|
41
|
-
|
90
|
+
bob = Person.create! :name => "Bob Smith", :location => "New York City"
|
91
|
+
bob.friendly_id #=> "bob-smith-from-new-york-city"
|
42
92
|
|
43
|
-
|
44
|
-
raise NotImplementedError
|
45
|
-
end
|
93
|
+
==== Providing Your Own Slug Processing Method
|
46
94
|
|
47
|
-
|
48
|
-
|
49
|
-
end
|
95
|
+
You can override {Slugged#normalize_friendly_id} in your model for total
|
96
|
+
control over the slug format.
|
50
97
|
|
51
|
-
|
52
|
-
def friendly_id_status
|
53
|
-
@friendly_id_status ||= Status.new(:record => self)
|
54
|
-
end
|
98
|
+
==== Locale-specific Transliterations
|
55
99
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
friendly_id = send(friendly_id_config.cache_column)
|
61
|
-
end
|
62
|
-
friendly_id || (slug.to_friendly_id if slug?)
|
63
|
-
end
|
100
|
+
Active Support's +parameterize+ uses
|
101
|
+
transliterate[http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-transliterate],
|
102
|
+
which in turn can use I18n's transliteration rules to consider the current
|
103
|
+
locale when replacing Latin characters:
|
64
104
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
105
|
+
# config/locales/de.yml
|
106
|
+
de:
|
107
|
+
i18n:
|
108
|
+
transliterate:
|
109
|
+
rule:
|
110
|
+
ü: "ue"
|
111
|
+
ö: "oe"
|
112
|
+
etc...
|
72
113
|
|
73
|
-
|
74
|
-
|
75
|
-
|
114
|
+
movie = Movie.create! :title => "Der Preis fürs Überleben"
|
115
|
+
movie.slug #=> "der-preis-fuers-ueberleben"
|
116
|
+
|
117
|
+
This functionality was in fact taken from earlier versions of FriendlyId.
|
118
|
+
=end
|
119
|
+
module Slugged
|
120
|
+
|
121
|
+
# Sets up behavior and configuration options for FriendlyId's slugging
|
122
|
+
# feature.
|
123
|
+
def self.included(model_class)
|
124
|
+
model_class.instance_eval do
|
125
|
+
friendly_id_config.class.send :include, Configuration
|
126
|
+
friendly_id_config.defaults[:slug_column] ||= 'slug'
|
127
|
+
friendly_id_config.defaults[:sequence_separator] ||= '--'
|
128
|
+
friendly_id_config.slug_sequencer_class ||= Class.new(SlugSequencer)
|
129
|
+
before_validation :set_slug
|
76
130
|
end
|
131
|
+
end
|
77
132
|
|
78
|
-
|
133
|
+
# Process the given value to make it suitable for use as a slug.
|
134
|
+
#
|
135
|
+
# This method is not intended to be invoked directly; FriendlyId uses it
|
136
|
+
# internaly to process strings into slugs.
|
137
|
+
#
|
138
|
+
# However, if FriendlyId's default slug generation doesn't suite your needs,
|
139
|
+
# you can override this method in your model class to control exactly how
|
140
|
+
# slugs are generated.
|
141
|
+
#
|
142
|
+
# === Example
|
143
|
+
#
|
144
|
+
# class Person < ActiveRecord::Base
|
145
|
+
# friendly_id :name_and_location
|
146
|
+
#
|
147
|
+
# def name_and_location
|
148
|
+
# "#{name} from #{location}"
|
149
|
+
# end
|
150
|
+
#
|
151
|
+
# # Use default slug, but uupper case and with underscores
|
152
|
+
# def normalize_friendly_id(string)
|
153
|
+
# super.upcase.gsub("-", "_")
|
154
|
+
# end
|
155
|
+
# end
|
156
|
+
#
|
157
|
+
# bob = Person.create! :name => "Bob Smith", :location => "New York City"
|
158
|
+
# bob.friendly_id #=> "BOB_SMITH_FROM_NEW_YORK_CITY"
|
159
|
+
#
|
160
|
+
# === More Resources
|
161
|
+
#
|
162
|
+
# You might want to look into Babosa[https://github.com/norman/babosa],
|
163
|
+
# which is the slugging library used by FriendlyId prior to version 4, which
|
164
|
+
# offers some specialized functionality missing from Active Support.
|
165
|
+
#
|
166
|
+
# @param [#to_s] value The value used as the basis of the slug.
|
167
|
+
# @return The candidate slug text, without a sequence.
|
168
|
+
def normalize_friendly_id(value)
|
169
|
+
value.to_s.parameterize
|
170
|
+
end
|
79
171
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
172
|
+
# Gets a new instance of the configured slug sequencing class.
|
173
|
+
#
|
174
|
+
# @see FriendlyId::SlugSequencer
|
175
|
+
def slug_sequencer
|
176
|
+
friendly_id_config.slug_sequencer_class.new(self)
|
177
|
+
end
|
178
|
+
|
179
|
+
# Sets the slug.
|
180
|
+
def set_slug
|
181
|
+
send "#{friendly_id_config.slug_column}=", slug_sequencer.generate
|
182
|
+
end
|
183
|
+
private :set_slug
|
184
|
+
|
185
|
+
# This module adds the +:slug_column+, and +:sequence_separator+, and
|
186
|
+
# +:slug_sequencer_class+ configuration options to
|
187
|
+
# {FriendlyId::Configuration FriendlyId::Configuration}.
|
188
|
+
module Configuration
|
189
|
+
attr_writer :slug_column, :sequence_separator
|
190
|
+
attr_accessor :slug_sequencer_class
|
191
|
+
|
192
|
+
# Makes FriendlyId use the slug column for querying.
|
193
|
+
# @return String The slug column.
|
194
|
+
def query_field
|
195
|
+
slug_column
|
88
196
|
end
|
89
197
|
|
90
|
-
#
|
91
|
-
|
92
|
-
|
198
|
+
# The string used to separate a slug base from a numeric sequence.
|
199
|
+
#
|
200
|
+
# By default, +--+ is used to separate the slug from the sequence.
|
201
|
+
# FriendlyId uses two dashes to distinguish sequences from slugs with
|
202
|
+
# numbers in their name.
|
203
|
+
#
|
204
|
+
# You can change the default separator by setting the
|
205
|
+
# {FriendlyId::Slugged::Configuration#sequence_separator
|
206
|
+
# sequence_separator} configuration option.
|
207
|
+
#
|
208
|
+
# For obvious reasons, you should avoid setting it to "+-+" unless you're
|
209
|
+
# sure you will never want to have a friendly id with a number in it.
|
210
|
+
# @return String The sequence separator string. Defaults to "+--+".
|
211
|
+
def sequence_separator
|
212
|
+
@sequence_separator or defaults[:sequence_separator]
|
93
213
|
end
|
94
214
|
|
95
|
-
#
|
96
|
-
|
97
|
-
|
98
|
-
if friendly_id_config.allow_nil?
|
99
|
-
(!slug? && !slug_text.blank?) || (slug? && slug_text_changed?)
|
100
|
-
else
|
101
|
-
!slug? || slug_text_changed?
|
102
|
-
end
|
215
|
+
# The column that will be used to store the generated slug.
|
216
|
+
def slug_column
|
217
|
+
@slug_column or defaults[:slug_column]
|
103
218
|
end
|
104
219
|
end
|
105
220
|
end
|
data/lib/friendly_id/version.rb
CHANGED
data/test/base_test.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require File.expand_path("../helper.rb", __FILE__)
|
2
|
+
|
3
|
+
class CoreTest < MiniTest::Unit::TestCase
|
4
|
+
include FriendlyId::Test
|
5
|
+
|
6
|
+
test "friendly_id should accept a base and a hash" do
|
7
|
+
klass = Class.new(ActiveRecord::Base) do
|
8
|
+
extend FriendlyId
|
9
|
+
friendly_id :foo, :use => :slugged, :slug_column => :bar
|
10
|
+
end
|
11
|
+
assert klass < FriendlyId::Slugged
|
12
|
+
assert_equal :foo, klass.friendly_id_config.base
|
13
|
+
assert_equal :bar, klass.friendly_id_config.slug_column
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
test "friendly_id should accept a block" do
|
18
|
+
klass = Class.new(ActiveRecord::Base) do
|
19
|
+
extend FriendlyId
|
20
|
+
friendly_id :foo do |config|
|
21
|
+
config.use :slugged
|
22
|
+
config.base = :foo
|
23
|
+
config.slug_column = :bar
|
24
|
+
end
|
25
|
+
end
|
26
|
+
assert klass < FriendlyId::Slugged
|
27
|
+
assert_equal :foo, klass.friendly_id_config.base
|
28
|
+
assert_equal :bar, klass.friendly_id_config.slug_column
|
29
|
+
end
|
30
|
+
|
31
|
+
test "the block passed to friendly_id should be evaluated before arguments" do
|
32
|
+
klass = Class.new(ActiveRecord::Base) do
|
33
|
+
extend FriendlyId
|
34
|
+
friendly_id :foo do |config|
|
35
|
+
config.base = :bar
|
36
|
+
end
|
37
|
+
end
|
38
|
+
assert_equal :foo, klass.friendly_id_config.base
|
39
|
+
end
|
40
|
+
|
41
|
+
test "should allow defaults to be set via a block" do
|
42
|
+
begin
|
43
|
+
FriendlyId.defaults do |config|
|
44
|
+
config.base = :foo
|
45
|
+
end
|
46
|
+
klass = Class.new(ActiveRecord::Base) do
|
47
|
+
extend FriendlyId
|
48
|
+
end
|
49
|
+
assert_equal :foo, klass.friendly_id_config.base
|
50
|
+
ensure
|
51
|
+
FriendlyId.instance_variable_set :@defaults, nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path("../helper", __FILE__)
|
2
|
+
|
3
|
+
class ConfigurationTest < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
include FriendlyId::Test
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@model_class = Class.new(ActiveRecord::Base)
|
9
|
+
end
|
10
|
+
|
11
|
+
test "should set model class on initialization" do
|
12
|
+
config = FriendlyId::Configuration.new @model_class
|
13
|
+
assert_equal @model_class, config.model_class
|
14
|
+
end
|
15
|
+
|
16
|
+
test "should set options on initialization if present" do
|
17
|
+
config = FriendlyId::Configuration.new @model_class, :base => "hello"
|
18
|
+
assert_equal "hello", config.base
|
19
|
+
end
|
20
|
+
|
21
|
+
test "should raise error if passed unrecognized option" do
|
22
|
+
assert_raises NoMethodError do
|
23
|
+
FriendlyId::Configuration.new @model_class, :foo => "bar"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/test/core_test.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path("../helper.rb", __FILE__)
|
2
|
+
|
3
|
+
Author, Book = 2.times.map do
|
4
|
+
Class.new(ActiveRecord::Base) do
|
5
|
+
extend FriendlyId
|
6
|
+
friendly_id :name
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class CoreTest < MiniTest::Unit::TestCase
|
11
|
+
|
12
|
+
include FriendlyId::Test
|
13
|
+
include FriendlyId::Test::Shared::Core
|
14
|
+
|
15
|
+
def model_class
|
16
|
+
Author
|
17
|
+
end
|
18
|
+
|
19
|
+
test "models don't use friendly_id by default" do
|
20
|
+
assert !Class.new(ActiveRecord::Base).respond_to?(:friendly_id)
|
21
|
+
end
|
22
|
+
|
23
|
+
test "model classes should have a friendly id config" do
|
24
|
+
assert model_class.friendly_id(:name).friendly_id_config
|
25
|
+
end
|
26
|
+
|
27
|
+
test "instances should have a friendly id" do
|
28
|
+
with_instance_of(model_class) {|record| assert record.friendly_id}
|
29
|
+
end
|
30
|
+
end
|
data/test/databases.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
mysql:
|
2
|
+
adapter: mysql2
|
3
|
+
database: friendly_id_test
|
4
|
+
username: root
|
5
|
+
hostname: localhost
|
6
|
+
encoding: utf8
|
7
|
+
|
8
|
+
postgres:
|
9
|
+
adapter: postgresql
|
10
|
+
host: localhost
|
11
|
+
port: 5432
|
12
|
+
username: postgres
|
13
|
+
database: friendly_id_test
|
14
|
+
encoding: utf8
|
15
|
+
|
16
|
+
sqlite3:
|
17
|
+
adapter: sqlite3
|
18
|
+
database: ":memory:"
|
19
|
+
encoding: utf8
|
data/test/helper.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
$: << File.expand_path("../../lib", __FILE__)
|
2
|
+
$: << File.expand_path("../", __FILE__)
|
3
|
+
$:.uniq!
|
4
|
+
|
5
|
+
require "rubygems"
|
6
|
+
require "bundler/setup"
|
7
|
+
require "mocha"
|
8
|
+
require "minitest/unit"
|
9
|
+
require "active_record"
|
10
|
+
require 'active_support/core_ext/time/conversions'
|
11
|
+
# require "active_support/core_ext/class"
|
12
|
+
|
13
|
+
if ENV["COVERAGE"]
|
14
|
+
require 'simplecov'
|
15
|
+
SimpleCov.start do
|
16
|
+
add_filter "test/"
|
17
|
+
add_filter "friendly_id/migration"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
require "friendly_id"
|
22
|
+
|
23
|
+
# If you want to see the ActiveRecord log, invoke the tests using `rake test LOG=true`
|
24
|
+
if ENV["LOG"]
|
25
|
+
require "logger"
|
26
|
+
ActiveRecord::Base.logger = Logger.new($stdout)
|
27
|
+
end
|
28
|
+
|
29
|
+
module FriendlyId
|
30
|
+
module Test
|
31
|
+
|
32
|
+
def self.included(base)
|
33
|
+
MiniTest::Unit.autorun
|
34
|
+
end
|
35
|
+
|
36
|
+
def transaction
|
37
|
+
ActiveRecord::Base.transaction { yield ; raise ActiveRecord::Rollback }
|
38
|
+
end
|
39
|
+
|
40
|
+
def with_instance_of(*args)
|
41
|
+
model_class = args.shift
|
42
|
+
args[0] ||= {:name => "a"}
|
43
|
+
transaction { yield model_class.create!(*args) }
|
44
|
+
end
|
45
|
+
|
46
|
+
module Database
|
47
|
+
extend self
|
48
|
+
|
49
|
+
def connect
|
50
|
+
ActiveRecord::Base.establish_connection config[driver]
|
51
|
+
version = ActiveRecord::VERSION::STRING
|
52
|
+
driver = FriendlyId::Test::Database.driver
|
53
|
+
engine = RUBY_ENGINE rescue "ruby"
|
54
|
+
message = "Using #{engine} #{RUBY_VERSION} AR #{version} with #{driver}"
|
55
|
+
puts "-" * 72
|
56
|
+
if in_memory?
|
57
|
+
ActiveRecord::Migration.verbose = false
|
58
|
+
Schema.up
|
59
|
+
puts "#{message} (in-memory)"
|
60
|
+
else
|
61
|
+
puts message
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def config
|
66
|
+
@config ||= YAML::load(File.open(File.expand_path("../databases.yml", __FILE__)))
|
67
|
+
end
|
68
|
+
|
69
|
+
def driver
|
70
|
+
(ENV["DB"] or "sqlite3").downcase
|
71
|
+
end
|
72
|
+
|
73
|
+
def in_memory?
|
74
|
+
config[driver]["database"] == ":memory:"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class Module
|
81
|
+
def test(name, &block)
|
82
|
+
define_method("test_#{name.gsub(/[^a-z0-9']/i, "_")}".to_sym, &block)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
require "schema"
|
87
|
+
require "shared"
|
88
|
+
FriendlyId::Test::Database.connect
|