sequel 0.4.4.2 → 0.4.5
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/CHANGELOG +971 -953
- data/Rakefile +58 -44
- data/lib/sequel/database.rb +60 -2
- data/lib/sequel/dataset.rb +1 -0
- data/lib/sequel/dataset/sql.rb +7 -2
- data/lib/sequel/model.rb +22 -14
- data/lib/sequel/model/base.rb +1 -0
- data/lib/sequel/model/record.rb +2 -0
- data/lib/sequel/model/schema.rb +1 -1
- data/lib/sequel/model/validations.rb +117 -0
- data/lib/sequel/schema/schema_generator.rb +8 -0
- data/lib/sequel/schema/schema_sql.rb +2 -0
- data/spec/database_spec.rb +15 -0
- data/spec/dataset_spec.rb +9 -0
- data/spec/model/base_spec.rb +148 -0
- data/spec/model/caching_spec.rb +148 -0
- data/spec/model/hooks_spec.rb +105 -0
- data/spec/model/plugins_spec.rb +59 -0
- data/spec/model/record_spec.rb +360 -0
- data/spec/model/relations_spec.rb +148 -0
- data/spec/model/schema_spec.rb +80 -0
- data/spec/model/validations_spec.rb +292 -0
- data/spec/model_spec.rb +331 -1102
- data/spec/rcov.opts +4 -0
- data/spec/spec.opts +1 -4
- data/spec/spec_helper.rb +3 -2
- metadata +15 -4
data/Rakefile
CHANGED
@@ -5,19 +5,24 @@ require "rake/rdoctask"
|
|
5
5
|
require "fileutils"
|
6
6
|
include FileUtils
|
7
7
|
|
8
|
+
##############################################################################
|
9
|
+
# Configuration
|
10
|
+
##############################################################################
|
8
11
|
NAME = "sequel"
|
9
|
-
VERS = "0.4.
|
12
|
+
VERS = "0.4.5"
|
10
13
|
CLEAN.include ["**/.*.sw?", "pkg/*", ".config", "doc/*", "coverage/*"]
|
11
|
-
RDOC_OPTS = [
|
14
|
+
RDOC_OPTS = [
|
15
|
+
"--quiet",
|
16
|
+
"--title", "Sequel: Concise ORM for Ruby",
|
12
17
|
"--opname", "index.html",
|
13
18
|
"--line-numbers",
|
14
19
|
"--main", "README",
|
15
|
-
"--inline-source"
|
16
|
-
|
17
|
-
desc "Packages up Sequel."
|
18
|
-
task :default => [:package]
|
19
|
-
task :package => [:clean]
|
20
|
+
"--inline-source"
|
21
|
+
]
|
20
22
|
|
23
|
+
##############################################################################
|
24
|
+
# RDoc
|
25
|
+
##############################################################################
|
21
26
|
task :doc => [:rdoc]
|
22
27
|
|
23
28
|
Rake::RDocTask.new do |rdoc|
|
@@ -28,8 +33,16 @@ Rake::RDocTask.new do |rdoc|
|
|
28
33
|
rdoc.rdoc_files.add ["README", "COPYING", "lib/sequel.rb", "lib/**/*.rb"]
|
29
34
|
end
|
30
35
|
|
36
|
+
##############################################################################
|
37
|
+
# Gem packaging
|
38
|
+
##############################################################################
|
39
|
+
desc "Packages up Sequel."
|
40
|
+
task :default => [:package]
|
41
|
+
task :package => [:clean]
|
42
|
+
|
31
43
|
spec = Gem::Specification.new do |s|
|
32
44
|
s.name = NAME
|
45
|
+
s.rubyforge_project = NAME
|
33
46
|
s.version = VERS
|
34
47
|
s.platform = Gem::Platform::RUBY
|
35
48
|
s.has_rdoc = true
|
@@ -42,40 +55,25 @@ spec = Gem::Specification.new do |s|
|
|
42
55
|
s.email = "ciconia@gmail.com"
|
43
56
|
s.homepage = "http://sequel.rubyforge.org"
|
44
57
|
s.executables = ["sequel"]
|
45
|
-
|
46
|
-
s.add_dependency("metaid")
|
47
|
-
s.add_dependency("ParseTree", ">= 2.0.0")
|
48
|
-
s.add_dependency("ruby2ruby")
|
49
|
-
|
50
58
|
s.required_ruby_version = ">= 1.8.4"
|
51
59
|
|
52
|
-
|
53
|
-
|
54
|
-
s.
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
s.summary = "Lightweight ORM library for Ruby"
|
67
|
-
s.description = s.summary
|
68
|
-
s.author = "Sharon Rosner"
|
69
|
-
s.email = "ciconia@gmail.com"
|
70
|
-
s.homepage = "http://sequel.rubyforge.org"
|
71
|
-
s.executables = ["sequel"]
|
72
|
-
|
73
|
-
s.add_dependency("metaid")
|
60
|
+
# Instead of requiring this, how about we simply use it if it's available
|
61
|
+
# by rescuing LoadError where we require it in model/validations.rb?
|
62
|
+
# s.add_dependency("validatable")
|
63
|
+
case RUBY_PLATFORM
|
64
|
+
when /mswin/
|
65
|
+
s.platform = Gem::Platform::CURRENT
|
66
|
+
when /java/
|
67
|
+
s.platform = "jruby"
|
68
|
+
else
|
69
|
+
s.platform = Gem::Platform::RUBY
|
70
|
+
s.add_dependency("metaid")
|
71
|
+
s.add_dependency("ParseTree", ">= 2.0.0")
|
72
|
+
s.add_dependency("ruby2ruby")
|
73
|
+
end
|
74
74
|
|
75
|
-
s.required_ruby_version = ">= 1.8.4"
|
76
|
-
|
77
75
|
s.files = %w(COPYING README Rakefile) + Dir.glob("{bin,doc,spec,lib}/**/*")
|
78
|
-
|
76
|
+
|
79
77
|
s.require_path = "lib"
|
80
78
|
s.bindir = "bin"
|
81
79
|
end
|
@@ -85,11 +83,9 @@ Rake::GemPackageTask.new(spec) do |p|
|
|
85
83
|
p.gem_spec = spec
|
86
84
|
end
|
87
85
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
end
|
92
|
-
|
86
|
+
##############################################################################
|
87
|
+
# installation & removal
|
88
|
+
##############################################################################
|
93
89
|
task :install do
|
94
90
|
sh %{rake package}
|
95
91
|
sh %{sudo gem install pkg/#{NAME}-#{VERS}}
|
@@ -104,6 +100,9 @@ task :uninstall => [:clean] do
|
|
104
100
|
sh %{sudo gem uninstall #{NAME}}
|
105
101
|
end
|
106
102
|
|
103
|
+
##############################################################################
|
104
|
+
# gem and rdoc release
|
105
|
+
##############################################################################
|
107
106
|
task :release => [:package] do
|
108
107
|
sh %{rubyforge login}
|
109
108
|
sh %{rubyforge add_release sequel sequel #{VERS} pkg/sequel-#{VERS}.tgz}
|
@@ -117,29 +116,44 @@ task :doc_rforge do
|
|
117
116
|
sh %{scp -r doc/rdoc/* ciconia@rubyforge.org:/var/www/gforge-projects/sequel}
|
118
117
|
end
|
119
118
|
|
119
|
+
##############################################################################
|
120
|
+
# specs
|
121
|
+
##############################################################################
|
120
122
|
require "spec/rake/spectask"
|
121
123
|
|
122
124
|
desc "Run specs with coverage"
|
123
125
|
Spec::Rake::SpecTask.new("spec") do |t|
|
124
126
|
t.spec_files = FileList["spec/*_spec.rb"]
|
125
|
-
t.
|
127
|
+
t.spec_opts = File.read("spec/spec.opts").split("\n")
|
128
|
+
t.rcov_opts = File.read("spec/rcov.opts").split("\n")
|
126
129
|
t.rcov = true
|
127
130
|
end
|
128
131
|
|
129
132
|
desc "Run specs without coverage"
|
130
133
|
Spec::Rake::SpecTask.new("spec_no_cov") do |t|
|
131
134
|
t.spec_files = FileList["spec/*_spec.rb"]
|
135
|
+
t.spec_opts = File.read("spec/spec.opts").split("\n")
|
132
136
|
end
|
133
137
|
|
134
138
|
desc "Run adapter specs without coverage"
|
135
139
|
Spec::Rake::SpecTask.new("spec_adapters") do |t|
|
136
140
|
t.spec_files = FileList["spec/adapters/*_spec.rb"]
|
141
|
+
t.spec_opts = File.read("spec/spec.opts").split("\n")
|
137
142
|
end
|
138
143
|
|
139
144
|
desc "Run all specs with coverage"
|
140
145
|
Spec::Rake::SpecTask.new("spec_all") do |t|
|
141
146
|
t.spec_files = FileList["spec/*_spec.rb", "spec/adapters/*_spec.rb"]
|
142
|
-
t.rcov_opts
|
147
|
+
t.rcov_opts = File.read("spec/rcov.opts").split("\n")
|
148
|
+
t.spec_opts = File.read("spec/spec.opts").split("\n")
|
149
|
+
t.rcov = true
|
150
|
+
end
|
151
|
+
|
152
|
+
desc "Run rcov only"
|
153
|
+
Spec::Rake::SpecTask.new("rcov") do |t|
|
154
|
+
t.rcov_opts = File.read("spec/rcov.opts").split("\n")
|
155
|
+
t.spec_opts = File.read("spec/spec.opts").split("\n")
|
156
|
+
t.spec_files = FileList["spec/*_spec.rb"]
|
143
157
|
t.rcov = true
|
144
158
|
end
|
145
159
|
|
data/lib/sequel/database.rb
CHANGED
@@ -188,39 +188,86 @@ module Sequel
|
|
188
188
|
names.each {|n| execute(drop_table_sql(n))}
|
189
189
|
end
|
190
190
|
|
191
|
+
# Renames a table:
|
192
|
+
#
|
193
|
+
# DB.tables #=> [:items]
|
194
|
+
# DB.rename_table :items, :old_items
|
195
|
+
# DB.tables #=> [:old_items]
|
191
196
|
def rename_table(*args)
|
192
197
|
execute(rename_table_sql(*args))
|
193
198
|
end
|
194
199
|
|
200
|
+
# Alters the given table with the specified block. Here are the currently
|
201
|
+
# available operations:
|
202
|
+
#
|
203
|
+
# DB.alter_table :items do
|
204
|
+
# add_column :category, :text, :default => 'ruby'
|
205
|
+
# drop_column :category
|
206
|
+
# rename_column :cntr, :counter
|
207
|
+
# set_column_type :value, :float
|
208
|
+
# set_column_default :value, :float
|
209
|
+
# add_index [:group, :category]
|
210
|
+
# drop_index [:group, :category]
|
211
|
+
# end
|
212
|
+
#
|
213
|
+
# Note that #add_column accepts all the options available for column
|
214
|
+
# definitions using create_table, and #add_index accepts all the options
|
215
|
+
# available for index definition.
|
195
216
|
def alter_table(name, &block)
|
196
217
|
g = Schema::AlterTableGenerator.new(self, &block)
|
197
218
|
alter_table_sql_list(name, g.operations).each {|sql| execute(sql)}
|
198
219
|
end
|
199
220
|
|
221
|
+
# Adds a column to the specified table. This method expects a column name,
|
222
|
+
# a datatype and optionally a hash with additional constraints and options:
|
223
|
+
#
|
224
|
+
# DB.add_column :items, :name, :text, :unique => true, :null => false
|
225
|
+
# DB.add_column :items, :category, :text, :default => 'ruby'
|
200
226
|
def add_column(table, *args)
|
201
227
|
alter_table(table) {add_column(*args)}
|
202
228
|
end
|
203
229
|
|
230
|
+
# Removes a column from the specified table:
|
231
|
+
#
|
232
|
+
# DB.drop_column :items, :category
|
204
233
|
def drop_column(table, *args)
|
205
234
|
alter_table(table) {drop_column(*args)}
|
206
235
|
end
|
207
236
|
|
237
|
+
# Renames a column in the specified table. This method expects the current
|
238
|
+
# column name and the new column name:
|
239
|
+
#
|
240
|
+
# DB.rename_column :items, :cntr, :counter
|
208
241
|
def rename_column(table, *args)
|
209
242
|
alter_table(table) {rename_column(*args)}
|
210
243
|
end
|
211
244
|
|
245
|
+
# Set the data type for the given column in the given table:
|
246
|
+
#
|
247
|
+
# DB.set_column_type :items, :price, :float
|
212
248
|
def set_column_type(table, *args)
|
213
249
|
alter_table(table) {set_column_type(*args)}
|
214
250
|
end
|
215
251
|
|
252
|
+
# Sets the default value for the given column in the given table:
|
253
|
+
#
|
254
|
+
# DB.set_column_default :items, :category, 'perl!'
|
255
|
+
def set_column_default(table, *args)
|
256
|
+
alter_table(table) {set_column_default(*args)}
|
257
|
+
end
|
258
|
+
|
216
259
|
# Adds an index to a table for the given columns:
|
217
260
|
#
|
218
|
-
# DB.add_index
|
219
|
-
# DB.add_index
|
261
|
+
# DB.add_index :posts, :title
|
262
|
+
# DB.add_index :posts, [:author, :title], :unique => true
|
220
263
|
def add_index(table, *args)
|
221
264
|
alter_table(table) {add_index(*args)}
|
222
265
|
end
|
223
266
|
|
267
|
+
# Removes an index for the given table and column/s:
|
268
|
+
#
|
269
|
+
# DB.drop_index :posts, :title
|
270
|
+
# DB.drop_index :posts, [:author, :title]
|
224
271
|
def drop_index(table, *args)
|
225
272
|
alter_table(table) {drop_index(*args)}
|
226
273
|
end
|
@@ -236,16 +283,27 @@ module Sequel
|
|
236
283
|
false
|
237
284
|
end
|
238
285
|
|
286
|
+
# Creates a view based on a dataset or an SQL string:
|
287
|
+
#
|
288
|
+
# DB.create_view(:cheap_items, "SELECT * FROM items WHERE price < 100")
|
289
|
+
# DB.create_view(:ruby_items, DB[:items].filter(:category => 'ruby'))
|
239
290
|
def create_view(name, source)
|
240
291
|
source = source.sql if source.is_a?(Dataset)
|
241
292
|
execute("CREATE VIEW #{name} AS #{source}")
|
242
293
|
end
|
243
294
|
|
295
|
+
# Creates a view, replacing it if it already exists:
|
296
|
+
#
|
297
|
+
# DB.create_or_replace_view(:cheap_items, "SELECT * FROM items WHERE price < 100")
|
298
|
+
# DB.create_or_replace_view(:ruby_items, DB[:items].filter(:category => 'ruby'))
|
244
299
|
def create_or_replace_view(name, source)
|
245
300
|
source = source.sql if source.is_a?(Dataset)
|
246
301
|
execute("CREATE OR REPLACE VIEW #{name} AS #{source}")
|
247
302
|
end
|
248
303
|
|
304
|
+
# Drops a view:
|
305
|
+
#
|
306
|
+
# DB.drop_view(:cheap_items)
|
249
307
|
def drop_view(name)
|
250
308
|
execute("DROP VIEW #{name}")
|
251
309
|
end
|
data/lib/sequel/dataset.rb
CHANGED
data/lib/sequel/dataset/sql.rb
CHANGED
@@ -454,7 +454,8 @@ module Sequel
|
|
454
454
|
"INSERT INTO #{@opts[:from]} DEFAULT VALUES"
|
455
455
|
elsif values.keys
|
456
456
|
fl = values.keys.map {|f| literal(f.to_sym)}
|
457
|
-
vl = transform_save(values.values)
|
457
|
+
vl = @transform ? transform_save(values.values) : values.values
|
458
|
+
vl.map! {|v| literal(v)}
|
458
459
|
"INSERT INTO #{@opts[:from]} (#{fl.join(COMMA_SEPARATOR)}) VALUES (#{vl.join(COMMA_SEPARATOR)})"
|
459
460
|
else
|
460
461
|
"INSERT INTO #{@opts[:from]} VALUES (#{literal(values)})"
|
@@ -498,7 +499,11 @@ module Sequel
|
|
498
499
|
if values.is_a?(Hash)
|
499
500
|
# get values from hash
|
500
501
|
values = transform_save(values) if @transform
|
501
|
-
set = values.map
|
502
|
+
set = values.map do |k, v|
|
503
|
+
# convert string key into symbol
|
504
|
+
k = k.to_sym if String === k
|
505
|
+
"#{literal(k)} = #{literal(v)}"
|
506
|
+
end.join(COMMA_SEPARATOR)
|
502
507
|
else
|
503
508
|
# copy values verbatim
|
504
509
|
set = values
|
data/lib/sequel/model.rb
CHANGED
@@ -227,18 +227,22 @@ module Sequel
|
|
227
227
|
class Model
|
228
228
|
alias_method :model, :class
|
229
229
|
end
|
230
|
+
|
230
231
|
end
|
231
232
|
|
232
|
-
require File.join(File.dirname(__FILE__),
|
233
|
-
require File.join(File.dirname(__FILE__),
|
234
|
-
require File.join(File.dirname(__FILE__),
|
235
|
-
require File.join(File.dirname(__FILE__),
|
236
|
-
require File.join(File.dirname(__FILE__),
|
237
|
-
require File.join(File.dirname(__FILE__),
|
238
|
-
require File.join(File.dirname(__FILE__),
|
233
|
+
require File.join(File.dirname(__FILE__), "model/base")
|
234
|
+
require File.join(File.dirname(__FILE__), "model/hooks")
|
235
|
+
require File.join(File.dirname(__FILE__), "model/record")
|
236
|
+
require File.join(File.dirname(__FILE__), "model/schema")
|
237
|
+
require File.join(File.dirname(__FILE__), "model/relations")
|
238
|
+
require File.join(File.dirname(__FILE__), "model/caching")
|
239
|
+
require File.join(File.dirname(__FILE__), "model/plugins")
|
240
|
+
require File.join(File.dirname(__FILE__), "model/validations")
|
239
241
|
|
240
242
|
module Sequel
|
243
|
+
|
241
244
|
class Model
|
245
|
+
|
242
246
|
# Defines a method that returns a filtered dataset.
|
243
247
|
def self.subset(name, *args, &block)
|
244
248
|
dataset.meta_def(name) {filter(*args, &block)}
|
@@ -253,6 +257,7 @@ module Sequel
|
|
253
257
|
dataset.filter(*args, &block).first
|
254
258
|
end
|
255
259
|
|
260
|
+
# TODO: doc
|
256
261
|
def self.[](*args)
|
257
262
|
args = args.first if (args.size == 1)
|
258
263
|
if args === true || args === false
|
@@ -261,6 +266,7 @@ module Sequel
|
|
261
266
|
dataset[(Hash === args) ? args : primary_key_hash(args)]
|
262
267
|
end
|
263
268
|
|
269
|
+
# TODO: doc
|
264
270
|
def self.fetch(*args)
|
265
271
|
db.fetch(*args).set_model(self)
|
266
272
|
end
|
@@ -273,6 +279,11 @@ module Sequel
|
|
273
279
|
|
274
280
|
############################################################################
|
275
281
|
|
282
|
+
# Deletes all records in the model's table.
|
283
|
+
def self.delete_all
|
284
|
+
dataset.delete
|
285
|
+
end
|
286
|
+
|
276
287
|
# Like delete_all, but invokes before_destroy and after_destroy hooks if used.
|
277
288
|
def self.destroy_all
|
278
289
|
if has_hooks?(:before_destroy) || has_hooks?(:after_destroy)
|
@@ -281,11 +292,7 @@ module Sequel
|
|
281
292
|
dataset.delete
|
282
293
|
end
|
283
294
|
end
|
284
|
-
|
285
|
-
def self.delete_all
|
286
|
-
dataset.delete
|
287
|
-
end
|
288
|
-
|
295
|
+
|
289
296
|
def self.is_dataset_magic_method?(m)
|
290
297
|
method_name = m.to_s
|
291
298
|
Sequel::Dataset::MAGIC_METHODS.each_key do |r|
|
@@ -303,15 +310,16 @@ module Sequel
|
|
303
310
|
respond_to?(m) ? send(m, *args, &block) : super(m, *args)
|
304
311
|
end
|
305
312
|
|
306
|
-
# Comprehensive description goes here!
|
313
|
+
# TODO: Comprehensive description goes here!
|
307
314
|
def self.join(*args)
|
308
315
|
table_name = dataset.opts[:from].first
|
309
316
|
dataset.join(*args).select(table_name.to_sym.ALL)
|
310
317
|
end
|
311
318
|
|
312
|
-
# Returns an array containing all
|
319
|
+
# Returns an array containing all of the models records.
|
313
320
|
def self.all
|
314
321
|
dataset.all
|
315
322
|
end
|
316
323
|
end
|
324
|
+
|
317
325
|
end
|
data/lib/sequel/model/base.rb
CHANGED
data/lib/sequel/model/record.rb
CHANGED
@@ -198,6 +198,7 @@ module Sequel
|
|
198
198
|
def new?
|
199
199
|
@new
|
200
200
|
end
|
201
|
+
alias :new_record? :new?
|
201
202
|
|
202
203
|
# Returns true when current instance exists, false otherwise.
|
203
204
|
def exists?
|
@@ -248,6 +249,7 @@ module Sequel
|
|
248
249
|
this.update(values)
|
249
250
|
values.each {|k, v| @values[k] = v}
|
250
251
|
end
|
252
|
+
alias_method :update, :set
|
251
253
|
|
252
254
|
# Reloads values from database and returns self.
|
253
255
|
def refresh
|
data/lib/sequel/model/schema.rb
CHANGED
@@ -0,0 +1,117 @@
|
|
1
|
+
module Sequel
|
2
|
+
class Model
|
3
|
+
# =Basic Sequel Validations
|
4
|
+
#
|
5
|
+
# Sequel validations are based on the Validatable gem http://validatable.rubyforge.org/
|
6
|
+
#
|
7
|
+
# To assign default validations to a sequel model:
|
8
|
+
#
|
9
|
+
# class MyModel < SequelModel(:items)
|
10
|
+
# validates do
|
11
|
+
# format_of...
|
12
|
+
# presence_of...
|
13
|
+
# acceptance_of...
|
14
|
+
# confirmation_of...
|
15
|
+
# length_of...
|
16
|
+
# true_for...
|
17
|
+
# numericality_of...
|
18
|
+
# format_of...
|
19
|
+
# validates_base...
|
20
|
+
# validates_each...
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# You may also perform the usual 'longhand' way to assign default model validates
|
25
|
+
# directly within the model class itself:
|
26
|
+
#
|
27
|
+
# class MyModel < SequelModel(:items)
|
28
|
+
# validates_format_of...
|
29
|
+
# validates_presence_of...
|
30
|
+
# validates_acceptance_of...
|
31
|
+
# validates_confirmation_of...
|
32
|
+
# validates_length_of...
|
33
|
+
# validates_true_for...
|
34
|
+
# validates_numericality_of...
|
35
|
+
# validates_format_of...
|
36
|
+
# validates_base...
|
37
|
+
# validates_each...
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# Each validation allows for arguments:
|
41
|
+
# TODO: fill the argument options in here
|
42
|
+
#
|
43
|
+
# =Advanced Sequel Validations
|
44
|
+
#
|
45
|
+
# TODO: verify that advanced validates work as stated (aka write specs)
|
46
|
+
# NOTE: experimental
|
47
|
+
#
|
48
|
+
# To store validates for conditional usage simply specify a name with which to store them
|
49
|
+
# class User < Sequel::Model
|
50
|
+
#
|
51
|
+
# # This set of validates becomes stored as :default and gets injected into the model.
|
52
|
+
# validates do
|
53
|
+
# # standard validates calls
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# validates(:registration) do
|
57
|
+
# # user registration specific validates
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# validates(:promotion) do
|
61
|
+
# # user promotion validates
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# To use the above validates:
|
67
|
+
#
|
68
|
+
# @user.valid? # Runs the default validations only.
|
69
|
+
# @user.valid?(:registration) # Runs both default and registration validations
|
70
|
+
# @user.valid?(:promotion) # Runs both default and promotion validations
|
71
|
+
#
|
72
|
+
# You may determine whether the model has validates via:
|
73
|
+
#
|
74
|
+
# has_validations? # will return true / false based on existence of validations on the model.
|
75
|
+
#
|
76
|
+
# You may also retrieve the validations block if needed:
|
77
|
+
#
|
78
|
+
# validates(:registration) # returns the registration validation block.
|
79
|
+
#
|
80
|
+
# validates() method parameters:
|
81
|
+
# a validations block - runs the validations block on the model & stores as :default
|
82
|
+
# a name and a validations block - stores the block under the name
|
83
|
+
# a name - returns a stored block of that name or nil
|
84
|
+
# nothing - returns true / false based on if validations exist for the model.
|
85
|
+
#
|
86
|
+
module Validations
|
87
|
+
class Generator
|
88
|
+
def initialize(model_class ,&block)
|
89
|
+
@model_class = model_class
|
90
|
+
instance_eval(&block)
|
91
|
+
end
|
92
|
+
|
93
|
+
def method_missing(method, *args)
|
94
|
+
method = :"validates_#{method}"
|
95
|
+
@model_class.send(method, *args)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
begin
|
101
|
+
require "validatable"
|
102
|
+
include ::Validatable
|
103
|
+
def self.validates(&block)
|
104
|
+
Validations::Generator.new(self, &block)
|
105
|
+
end
|
106
|
+
# return true if there are validations stored, false otherwise
|
107
|
+
def self.has_validations?
|
108
|
+
validations.length > 0 ? true : false
|
109
|
+
end
|
110
|
+
rescue LoadError
|
111
|
+
STDERR.puts <<-MESSAGE
|
112
|
+
Install the validatable gem in order to use Sequel Model validations
|
113
|
+
If you would like model validations to work, install the validatable gem
|
114
|
+
MESSAGE
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|