sequel_model 0.3 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +4 -0
- data/Rakefile +1 -1
- data/lib/sequel_model/base.rb +5 -4
- data/lib/sequel_model/record.rb +2 -2
- data/lib/sequel_model/relations.rb +6 -6
- data/lib/sequel_model/relationships.rb +233 -0
- data/lib/sequel_model.rb +14 -13
- data/spec/base_spec.rb +37 -2
- data/spec/relations_spec.rb +0 -14
- data/spec/relationships_spec.rb +12 -0
- data/spec/validations_spec.rb +13 -13
- metadata +4 -2
data/CHANGELOG
CHANGED
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ include FileUtils
|
|
9
9
|
# Configuration
|
10
10
|
##############################################################################
|
11
11
|
NAME = "sequel_model"
|
12
|
-
VERS = "0.3"
|
12
|
+
VERS = "0.3.1"
|
13
13
|
CLEAN.include ["**/.*.sw?", "pkg/*", ".config", "doc/*", "coverage/*"]
|
14
14
|
RDOC_OPTS = [
|
15
15
|
"--quiet",
|
data/lib/sequel_model/base.rb
CHANGED
@@ -19,12 +19,13 @@ module Sequel
|
|
19
19
|
|
20
20
|
# Returns the dataset associated with the Model class.
|
21
21
|
def self.dataset
|
22
|
-
|
22
|
+
@dataset ||= super_dataset ||
|
23
|
+
(!(n = name).empty? && db[n.underscore.pluralize.to_sym]) ||
|
23
24
|
(raise Error, "No dataset associated with #{self}")
|
24
25
|
end
|
25
26
|
|
26
27
|
def self.super_dataset # :nodoc:
|
27
|
-
superclass.dataset if superclass
|
28
|
+
superclass.dataset if (superclass != Sequel::Model) && superclass.respond_to?(:dataset)
|
28
29
|
end
|
29
30
|
|
30
31
|
# Returns the columns in the result set in their original order.
|
@@ -79,8 +80,8 @@ module Sequel
|
|
79
80
|
# Makes given dataset inherited.
|
80
81
|
#
|
81
82
|
# === Example:
|
82
|
-
# class Comment < Sequel::Model(:
|
83
|
-
# table_name # => :
|
83
|
+
# class Comment < Sequel::Model(:something)
|
84
|
+
# table_name # => :something
|
84
85
|
#
|
85
86
|
# # ...
|
86
87
|
#
|
data/lib/sequel_model/record.rb
CHANGED
@@ -53,12 +53,12 @@ module Sequel
|
|
53
53
|
# Sets primary key, regular and composite are possible.
|
54
54
|
#
|
55
55
|
# == Example:
|
56
|
-
# class Tagging < Sequel::Model
|
56
|
+
# class Tagging < Sequel::Model
|
57
57
|
# # composite key
|
58
58
|
# set_primary_key :taggable_id, :tag_id
|
59
59
|
# end
|
60
60
|
#
|
61
|
-
# class Person < Sequel::Model
|
61
|
+
# class Person < Sequel::Model
|
62
62
|
# # regular key
|
63
63
|
# set_primary_key :person_id
|
64
64
|
# end
|
@@ -4,10 +4,10 @@ module Sequel
|
|
4
4
|
|
5
5
|
# Creates a 1-1 relationship by defining an association method, e.g.:
|
6
6
|
#
|
7
|
-
# class Session < Sequel::Model
|
7
|
+
# class Session < Sequel::Model
|
8
8
|
# end
|
9
9
|
#
|
10
|
-
# class Node < Sequel::Model
|
10
|
+
# class Node < Sequel::Model
|
11
11
|
# one_to_one :producer, :from => Session
|
12
12
|
# # which is equivalent to
|
13
13
|
# def producer
|
@@ -58,10 +58,10 @@ module Sequel
|
|
58
58
|
|
59
59
|
# Creates a 1-N relationship by defining an association method, e.g.:
|
60
60
|
#
|
61
|
-
# class Book < Sequel::Model
|
61
|
+
# class Book < Sequel::Model
|
62
62
|
# end
|
63
63
|
#
|
64
|
-
# class Author < Sequel::Model
|
64
|
+
# class Author < Sequel::Model
|
65
65
|
# one_to_many :books, :from => Book
|
66
66
|
# # which is equivalent to
|
67
67
|
# def books
|
@@ -92,7 +92,7 @@ module Sequel
|
|
92
92
|
# Database modelling is generally done with an ER (Entity Relationship) diagram.
|
93
93
|
# Shouldn't ORM's facilitate simlilar specification?
|
94
94
|
|
95
|
-
# class Post < Sequel::Model
|
95
|
+
# class Post < Sequel::Model
|
96
96
|
# relationships do
|
97
97
|
# # Specify the relationships that exist with the User model (users table)
|
98
98
|
# # These relationships are precisely the ER diagram connecting arrows.
|
@@ -111,7 +111,7 @@ module Sequel
|
|
111
111
|
# ?parameters may be :zero, :one, :many which specifies the cardinality of the connection
|
112
112
|
|
113
113
|
# Example:
|
114
|
-
# class Post < Sequel::Model
|
114
|
+
# class Post < Sequel::Model
|
115
115
|
# relationships do
|
116
116
|
# has :one, :blog, :required => true # blog_id field, cannot be null
|
117
117
|
# has :one, :account # account_id field
|
@@ -0,0 +1,233 @@
|
|
1
|
+
# = Sequel Relationships
|
2
|
+
# Database modelling is generally done with an ER (Entity Relationship) diagram.
|
3
|
+
# Shouldn't ORM's facilitate simlilar specification?
|
4
|
+
|
5
|
+
# class Post < Sequel::Model
|
6
|
+
# relationships do
|
7
|
+
# # Specify the relationships that exist with the User model (users table)
|
8
|
+
# # These relationships are precisely the ER diagram connecting arrows.
|
9
|
+
# end
|
10
|
+
# end
|
11
|
+
|
12
|
+
#
|
13
|
+
# = Relationships
|
14
|
+
#
|
15
|
+
# are specifications of the ends of the ER diagrams connectors that are touching
|
16
|
+
# the current model.
|
17
|
+
#
|
18
|
+
# one_to_one, has_one
|
19
|
+
# many_to_one, belongs_to
|
20
|
+
# many_to_many, has_many
|
21
|
+
|
22
|
+
# ?parameters may be :zero, :one, :many which specifies the cardinality of the connection
|
23
|
+
|
24
|
+
# Example:
|
25
|
+
# class Post < Sequel::Model
|
26
|
+
# relationships do
|
27
|
+
# has :one, :blog, :required => true, :normalized => false # uses a blog_id field, which cannot be null, in the Post model
|
28
|
+
# has :one, :account # uses a join table called accounts_posts to link the post with it's account.
|
29
|
+
# has :many, :comments # uses a comments_posts join table
|
30
|
+
# has :many, :authors, :required => true # authors_posts join table, requires at least one author
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
#
|
35
|
+
# Relationship API Details
|
36
|
+
#
|
37
|
+
|
38
|
+
#
|
39
|
+
# == belongs_to
|
40
|
+
#
|
41
|
+
|
42
|
+
# Defines an blog and blog= method
|
43
|
+
# belongs_to :blog
|
44
|
+
|
45
|
+
# Same, but uses "b_id" as the blog's id field.
|
46
|
+
# belongs_to :blog, :key => :b_id
|
47
|
+
|
48
|
+
# has_many :comments
|
49
|
+
# * Defines comments method which will query the join table appropriately.
|
50
|
+
# * Checks to see if a "comments_posts" join table exists (alphabetical order)
|
51
|
+
# ** If it does not exist, will create the join table.
|
52
|
+
# ** If options are passed in these will be used to further define the join table.
|
53
|
+
|
54
|
+
|
55
|
+
# Benefits:
|
56
|
+
# * Normalized DB
|
57
|
+
# * Easy to define join objects
|
58
|
+
# * Efficient queries, database gets to use indexed fields (pkeys) instead of a string field and an id.
|
59
|
+
#
|
60
|
+
# For example, polymorphic associations now become:
|
61
|
+
# [user] 1-* [addresses_users] *-1 [addresses]
|
62
|
+
# [companies] 1-* [addresses_companies] *-1 [addresses]
|
63
|
+
# [clients] 1-* [addresses_clients] *-1 [addresses]
|
64
|
+
# it is automatically polymorphic by specifying the has relationship inside the 2User and Company tables to addresses. Addresses themselves don't care. so we have by default polymorphism.
|
65
|
+
# If you need to talk about a 'Company Address' then you can subclass, CompanyAddress < Address and do has :many, :company_addresses
|
66
|
+
|
67
|
+
module Sequel
|
68
|
+
|
69
|
+
class Model
|
70
|
+
|
71
|
+
module Relationships
|
72
|
+
class Generator
|
73
|
+
def initialize(model_class, &block)
|
74
|
+
@model_class = model_class
|
75
|
+
instance_eval(&block)
|
76
|
+
end
|
77
|
+
|
78
|
+
def method_missing(method, *args)
|
79
|
+
@model_class.send(method, *args)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class << self
|
85
|
+
cattr_reader :model_relationships
|
86
|
+
@@model_relationships = []
|
87
|
+
|
88
|
+
def relationship_exists?(arity,relation)
|
89
|
+
@@model_relationships.detect do |relation|
|
90
|
+
relation[:arity] == arity &&
|
91
|
+
relation[:klass] == relation
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# has arity<Symbol>, model<Symbol>
|
96
|
+
# has :one, :blog, :required => true # blog_id field, cannot be null
|
97
|
+
# has :one, :account # account_id field
|
98
|
+
# has :many, :comments # comments_posts join table
|
99
|
+
def has(arity, klass, options = {})
|
100
|
+
unless [:one,:many].include? arity
|
101
|
+
raise Sequel::Error, "Arity must be specified {:one, :many}."
|
102
|
+
end
|
103
|
+
|
104
|
+
#unless const_defined?(klass.to_s.camel_case)
|
105
|
+
#raise Sequel::Error, "#{klass.to_s.camel_case} does not exist"
|
106
|
+
#end
|
107
|
+
|
108
|
+
# Make sure the join table exists
|
109
|
+
auto_create_join_table(klass, options)
|
110
|
+
|
111
|
+
if relationship_exists?(arity, klass)
|
112
|
+
raise Sequel::Error, "The relationship #{self.class.name} has #{arity}, #{klass} is already defined."
|
113
|
+
end
|
114
|
+
|
115
|
+
# Store the relationship
|
116
|
+
@@model_relationships << {
|
117
|
+
:arity => arity,
|
118
|
+
:klass => klass,
|
119
|
+
:options => options
|
120
|
+
}
|
121
|
+
|
122
|
+
# Define relationship methods
|
123
|
+
after_initialize do
|
124
|
+
define_relationship_method arity, klass, options
|
125
|
+
end
|
126
|
+
|
127
|
+
#unless normalized
|
128
|
+
# :required => true # The relationship must be populated to save
|
129
|
+
# can only be used with normalized => false :
|
130
|
+
#end
|
131
|
+
# save the relationship
|
132
|
+
end
|
133
|
+
|
134
|
+
# the proxy methods has_xxx ... , simply pass thru to to has :xxx, ...
|
135
|
+
def has_one(klass, options = {})
|
136
|
+
has :one, klass, options
|
137
|
+
end
|
138
|
+
|
139
|
+
def has_many(klass, options = {})
|
140
|
+
has :many, klass, options
|
141
|
+
end
|
142
|
+
|
143
|
+
def belongs_to(klass, options = {})
|
144
|
+
has :one, klass, options
|
145
|
+
end
|
146
|
+
|
147
|
+
# returns true if exists, false if not
|
148
|
+
def join_table?(first, second)
|
149
|
+
# we still have to test this out
|
150
|
+
db[join_table(first, second)].table_exists?
|
151
|
+
end
|
152
|
+
|
153
|
+
# TODO: Move this elsewhere? outside relationships?
|
154
|
+
# creates a join table given two table names
|
155
|
+
def create_join_table(first, second)
|
156
|
+
first_key, second_key = "#{first}_id", "#{second}_id"
|
157
|
+
db.create_table join_table(first, second).to_sym do
|
158
|
+
#primary_key [first_key.to_sym, second_key.to_sym]
|
159
|
+
integer first_key, :null => false
|
160
|
+
integer second_key, :null => false
|
161
|
+
end unless join_table?(first, second)
|
162
|
+
end
|
163
|
+
|
164
|
+
def create_join_table!(first, second)
|
165
|
+
db.drop_table join_table(first, second)
|
166
|
+
create_join_table(first, second)
|
167
|
+
end
|
168
|
+
|
169
|
+
def auto_create_join_table!(klass)
|
170
|
+
auto_create_join_table(klass, :force => true)
|
171
|
+
end
|
172
|
+
|
173
|
+
def auto_create_join_table(klass, options = {})
|
174
|
+
first, second = table_name, klass.to_s.pluralize
|
175
|
+
if join_table?(first, second) && options[:force] == true
|
176
|
+
create_join_table!(first, second)
|
177
|
+
else
|
178
|
+
create_join_table(first, second)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
# Given two models, it outputs the join table name
|
183
|
+
# which is sorted alphabetically with each table name pluralized
|
184
|
+
# Examples:
|
185
|
+
# join_table(user, post) #=> :posts_users
|
186
|
+
# join_table(users, posts) #=> :posts_users
|
187
|
+
def join_table(first, second)
|
188
|
+
first, second = first.to_s.pluralize, second.to_s.pluralize
|
189
|
+
[first, second].sort.join("_").to_sym
|
190
|
+
end
|
191
|
+
|
192
|
+
# relationships do
|
193
|
+
# ...
|
194
|
+
# end
|
195
|
+
def relationships(&block)
|
196
|
+
Relationships::Generator.new(self, &block)
|
197
|
+
end
|
198
|
+
|
199
|
+
# return true if there are validations stored, false otherwise
|
200
|
+
def has_relationships?
|
201
|
+
model_relationships.length > 0 ? true : false
|
202
|
+
end
|
203
|
+
|
204
|
+
# TODO: figure out what we want to do with these...
|
205
|
+
# "FooBar".snake_case #=> "foo_bar"
|
206
|
+
def snake_case
|
207
|
+
gsub(/\B[A-Z]/, '_\&').downcase
|
208
|
+
end
|
209
|
+
|
210
|
+
# "foo_bar".camel_case #=> "FooBar"
|
211
|
+
def camel_case
|
212
|
+
split('_').map{|e| e.capitalize}.join
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Defines relationship method from the current class to the klass specified
|
217
|
+
def define_relationship_method(arity, relation, options)
|
218
|
+
if arity == :one
|
219
|
+
self.instance_eval "
|
220
|
+
def #{relation}
|
221
|
+
self.db.dataset.left_outer_join(#{relation}, :id => :#{relation.to_s.singularize}_id).limit(1)
|
222
|
+
end
|
223
|
+
"
|
224
|
+
elsif arity == :many
|
225
|
+
self.instance_eval "
|
226
|
+
def #{relation}
|
227
|
+
self.db.dataset.left_outer_join(#{relation}, :id => :#{relation.to_s.singularize}_id)
|
228
|
+
end
|
229
|
+
"
|
230
|
+
end
|
231
|
+
end # define_relationship_method
|
232
|
+
end # Model
|
233
|
+
end # Sequel
|
data/lib/sequel_model.rb
CHANGED
@@ -13,7 +13,7 @@ module Sequel
|
|
13
13
|
# You can also use the shorthand form:
|
14
14
|
#
|
15
15
|
# DB = Sequel('sqlite:/blog.db')
|
16
|
-
# class Post < Sequel::Model
|
16
|
+
# class Post < Sequel::Model
|
17
17
|
# end
|
18
18
|
#
|
19
19
|
# === Model instances
|
@@ -28,7 +28,7 @@ module Sequel
|
|
28
28
|
#
|
29
29
|
# Sequel models allow you to use any column as a primary key, and even composite keys made from multiple columns:
|
30
30
|
#
|
31
|
-
# class Post < Sequel::Model
|
31
|
+
# class Post < Sequel::Model
|
32
32
|
# set_primary_key [:category, :title]
|
33
33
|
# end
|
34
34
|
#
|
@@ -100,7 +100,7 @@ module Sequel
|
|
100
100
|
#
|
101
101
|
# Hooks are defined by supplying a block:
|
102
102
|
#
|
103
|
-
# class Post < Sequel::Model
|
103
|
+
# class Post < Sequel::Model
|
104
104
|
# after_create do
|
105
105
|
# set(:created_at => Time.now)
|
106
106
|
# end
|
@@ -128,17 +128,17 @@ module Sequel
|
|
128
128
|
#
|
129
129
|
# The most straightforward way to define an association in a Sequel model is as a regular instance method:
|
130
130
|
#
|
131
|
-
# class Post < Sequel::Model
|
131
|
+
# class Post < Sequel::Model
|
132
132
|
# def author; Author[author_id]; end
|
133
133
|
# end
|
134
134
|
#
|
135
|
-
# class Author < Sequel::Model
|
135
|
+
# class Author < Sequel::Model
|
136
136
|
# def posts; Post.filter(:author_id => pk); end
|
137
137
|
# end
|
138
138
|
#
|
139
139
|
# Sequel also provides two macros to assist with common types of associations. The one_to_one macro is roughly equivalent to ActiveRecord?'s belongs_to macro. It defines both getter and setter methods for the association:
|
140
140
|
#
|
141
|
-
# class Post < Sequel::Model
|
141
|
+
# class Post < Sequel::Model
|
142
142
|
# one_to_one :author, :from => Author
|
143
143
|
# end
|
144
144
|
#
|
@@ -147,7 +147,7 @@ module Sequel
|
|
147
147
|
#
|
148
148
|
# The one_to_many macro is roughly equivalent to ActiveRecord's has_many macro:
|
149
149
|
#
|
150
|
-
# class Author < Sequel::Model
|
150
|
+
# class Author < Sequel::Model
|
151
151
|
# one_to_many :posts, :from => Post, :key => :author_id
|
152
152
|
# end
|
153
153
|
#
|
@@ -160,7 +160,7 @@ module Sequel
|
|
160
160
|
# require 'memcache'
|
161
161
|
# CACHE = MemCache.new 'localhost:11211', :namespace => 'blog'
|
162
162
|
#
|
163
|
-
# class Author < Sequel::Model
|
163
|
+
# class Author < Sequel::Model
|
164
164
|
# set_cache CACHE, :ttl => 3600
|
165
165
|
# end
|
166
166
|
#
|
@@ -171,7 +171,7 @@ module Sequel
|
|
171
171
|
#
|
172
172
|
# The obvious way to add table-wide logic is to define class methods to the model class definition. That way you can define subsets of the underlying dataset, change the ordering, or perform actions on multiple records:
|
173
173
|
#
|
174
|
-
# class Post < Sequel::Model
|
174
|
+
# class Post < Sequel::Model
|
175
175
|
# def self.old_posts
|
176
176
|
# filter {:stamp < 30.days.ago}
|
177
177
|
# end
|
@@ -183,7 +183,7 @@ module Sequel
|
|
183
183
|
#
|
184
184
|
# You can also implement table-wide logic by defining methods on the dataset:
|
185
185
|
#
|
186
|
-
# class Post < Sequel::Model
|
186
|
+
# class Post < Sequel::Model
|
187
187
|
# def dataset.old_posts
|
188
188
|
# filter {:stamp < 30.days.ago}
|
189
189
|
# end
|
@@ -199,7 +199,7 @@ module Sequel
|
|
199
199
|
#
|
200
200
|
# Sequel models also provide a short hand notation for filters:
|
201
201
|
#
|
202
|
-
# class Post < Sequel::Model
|
202
|
+
# class Post < Sequel::Model
|
203
203
|
# subset(:old_posts) {:stamp < 30.days.ago}
|
204
204
|
# subset :invisible, :visible => false
|
205
205
|
# end
|
@@ -208,7 +208,7 @@ module Sequel
|
|
208
208
|
#
|
209
209
|
# Model classes can also be used as a place to define your table schema and control it. The schema DSL is exactly the same provided by Sequel::Schema::Generator:
|
210
210
|
#
|
211
|
-
# class Post < Sequel::Model
|
211
|
+
# class Post < Sequel::Model
|
212
212
|
# set_schema do
|
213
213
|
# primary_key :id
|
214
214
|
# text :title
|
@@ -230,8 +230,9 @@ module Sequel
|
|
230
230
|
|
231
231
|
end
|
232
232
|
|
233
|
+
# TODO: add relationships when complete:
|
233
234
|
files = %w[
|
234
|
-
base hooks record schema relations
|
235
|
+
base hooks record schema relations
|
235
236
|
caching plugins validations
|
236
237
|
]
|
237
238
|
dir = File.join(File.dirname(__FILE__), "sequel_model")
|
data/spec/base_spec.rb
CHANGED
@@ -135,8 +135,7 @@ describe "Model#serialize" do
|
|
135
135
|
end
|
136
136
|
|
137
137
|
describe Sequel::Model, "super_dataset" do
|
138
|
-
|
139
|
-
before(:each) do
|
138
|
+
setup do
|
140
139
|
MODEL_DB.reset
|
141
140
|
class SubClass < Sequel::Model(:items) ; end
|
142
141
|
end
|
@@ -146,5 +145,41 @@ describe Sequel::Model, "super_dataset" do
|
|
146
145
|
Sequel::Model(:items).should_receive(:dataset)
|
147
146
|
SubClass.super_dataset
|
148
147
|
end
|
148
|
+
end
|
149
149
|
|
150
|
+
describe Sequel::Model, "dataset" do
|
151
|
+
setup do
|
152
|
+
@a = Class.new(Sequel::Model(:items))
|
153
|
+
@b = Class.new(Sequel::Model)
|
154
|
+
|
155
|
+
class Elephant < Sequel::Model(:ele1)
|
156
|
+
end
|
157
|
+
|
158
|
+
class Maggot < Sequel::Model
|
159
|
+
end
|
160
|
+
|
161
|
+
class ShoeSize < Sequel::Model
|
162
|
+
end
|
163
|
+
|
164
|
+
class BootSize < ShoeSize
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
specify "should default to the plural of the class name" do
|
169
|
+
Maggot.dataset.sql.should == 'SELECT * FROM maggots'
|
170
|
+
ShoeSize.dataset.sql.should == 'SELECT * FROM shoe_sizes'
|
171
|
+
end
|
172
|
+
|
173
|
+
specify "should return the dataset for the superclass if available" do
|
174
|
+
BootSize.dataset.sql.should == 'SELECT * FROM shoe_sizes'
|
175
|
+
end
|
176
|
+
|
177
|
+
specify "should return the correct dataset if set explicitly" do
|
178
|
+
Elephant.dataset.sql.should == 'SELECT * FROM ele1'
|
179
|
+
@a.dataset.sql.should == 'SELECT * FROM items'
|
180
|
+
end
|
181
|
+
|
182
|
+
specify "should raise if no dataset is explicitly set and the class is anonymous" do
|
183
|
+
proc {@b.dataset}.should raise_error(Sequel::Error)
|
184
|
+
end
|
150
185
|
end
|
data/spec/relations_spec.rb
CHANGED
@@ -93,11 +93,6 @@ describe Sequel::Model, "one_to_one" do
|
|
93
93
|
d.values.should == {:id => 1, :parent_id => 6677}
|
94
94
|
$sqls.last.should == "UPDATE nodes SET parent_id = 6677 WHERE (id = 1)"
|
95
95
|
end
|
96
|
-
|
97
|
-
it "should warn with a depreciation notice if :class option was used" do
|
98
|
-
pending("write this spec")
|
99
|
-
end
|
100
|
-
|
101
96
|
end
|
102
97
|
|
103
98
|
describe Sequel::Model, "one_to_many" do
|
@@ -138,13 +133,4 @@ describe Sequel::Model, "one_to_many" do
|
|
138
133
|
a.should be_a_kind_of(Sequel::Dataset)
|
139
134
|
a.sql.should == 'SELECT * FROM abc WHERE (node_id = 1234)'
|
140
135
|
end
|
141
|
-
|
142
|
-
it "should warn with a depreciation notice if :class option was used" do
|
143
|
-
pending("write this spec")
|
144
|
-
end
|
145
|
-
|
146
|
-
it "should warn with a depreciation notice if :on option was used" do
|
147
|
-
pending("write this spec")
|
148
|
-
end
|
149
|
-
|
150
136
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
+
|
3
|
+
__END__
|
4
|
+
|
5
|
+
describe Sequel::Model::Relationships, "has :one" do
|
6
|
+
end
|
7
|
+
|
8
|
+
describe Sequel::Model::Relationships, "has :many" do
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Sequel::Model::Relationships, "belongs_to" do
|
12
|
+
end
|
data/spec/validations_spec.rb
CHANGED
@@ -293,7 +293,7 @@ end
|
|
293
293
|
describe Sequel::Model, "Validations" do
|
294
294
|
|
295
295
|
before(:all) do
|
296
|
-
class Person < Sequel::Model
|
296
|
+
class Person < Sequel::Model
|
297
297
|
def columns
|
298
298
|
[:id,:name,:first_name,:last_name,:middle_name,:initials,:age, :terms]
|
299
299
|
end
|
@@ -302,19 +302,19 @@ describe Sequel::Model, "Validations" do
|
|
302
302
|
class Smurf < Person
|
303
303
|
end
|
304
304
|
|
305
|
-
class Cow < Sequel::Model
|
305
|
+
class Cow < Sequel::Model
|
306
306
|
def columns
|
307
307
|
[:id, :name, :got_milk]
|
308
308
|
end
|
309
309
|
end
|
310
310
|
|
311
|
-
class User < Sequel::Model
|
311
|
+
class User < Sequel::Model
|
312
312
|
def columns
|
313
313
|
[:id, :username, :password]
|
314
314
|
end
|
315
315
|
end
|
316
316
|
|
317
|
-
class Address < Sequel::Model
|
317
|
+
class Address < Sequel::Model
|
318
318
|
def columns
|
319
319
|
[:id, :zip_code]
|
320
320
|
end
|
@@ -322,7 +322,7 @@ describe Sequel::Model, "Validations" do
|
|
322
322
|
end
|
323
323
|
|
324
324
|
it "should validate the acceptance of a column" do
|
325
|
-
class Cow < Sequel::Model
|
325
|
+
class Cow < Sequel::Model
|
326
326
|
validations.clear
|
327
327
|
validates_acceptance_of :got_milk, :accept => 'blah', :allow_nil => false
|
328
328
|
end
|
@@ -336,7 +336,7 @@ describe Sequel::Model, "Validations" do
|
|
336
336
|
end
|
337
337
|
|
338
338
|
it "should validate the confirmation of a column" do
|
339
|
-
class User < Sequel::Model
|
339
|
+
class User < Sequel::Model
|
340
340
|
def password_confirmation
|
341
341
|
"test"
|
342
342
|
end
|
@@ -354,7 +354,7 @@ describe Sequel::Model, "Validations" do
|
|
354
354
|
end
|
355
355
|
|
356
356
|
it "should validate format of column" do
|
357
|
-
class Person < Sequel::Model
|
357
|
+
class Person < Sequel::Model
|
358
358
|
validates_format_of :first_name, :with => /^[a-zA-Z]+$/
|
359
359
|
end
|
360
360
|
|
@@ -369,7 +369,7 @@ describe Sequel::Model, "Validations" do
|
|
369
369
|
# end
|
370
370
|
|
371
371
|
it "should validate length of column" do
|
372
|
-
class Person < Sequel::Model
|
372
|
+
class Person < Sequel::Model
|
373
373
|
validations.clear
|
374
374
|
validates_length_of :first_name, :maximum => 30
|
375
375
|
validates_length_of :last_name, :minimum => 30
|
@@ -401,7 +401,7 @@ describe Sequel::Model, "Validations" do
|
|
401
401
|
end
|
402
402
|
|
403
403
|
it "should validate numericality of column" do
|
404
|
-
class Person < Sequel::Model
|
404
|
+
class Person < Sequel::Model
|
405
405
|
validations.clear
|
406
406
|
validates_numericality_of :age
|
407
407
|
end
|
@@ -415,7 +415,7 @@ describe Sequel::Model, "Validations" do
|
|
415
415
|
end
|
416
416
|
|
417
417
|
it "should validate the presence of a column" do
|
418
|
-
class Cow < Sequel::Model
|
418
|
+
class Cow < Sequel::Model
|
419
419
|
validations.clear
|
420
420
|
validates_presence_of :name
|
421
421
|
end
|
@@ -429,7 +429,7 @@ describe Sequel::Model, "Validations" do
|
|
429
429
|
end
|
430
430
|
|
431
431
|
it "should have a validates block that calls multple validations" do
|
432
|
-
class Person < Sequel::Model
|
432
|
+
class Person < Sequel::Model
|
433
433
|
validations.clear
|
434
434
|
validates do
|
435
435
|
format_of :first_name, :with => /^[a-zA-Z]+$/
|
@@ -448,7 +448,7 @@ describe Sequel::Model, "Validations" do
|
|
448
448
|
|
449
449
|
it "should allow 'longhand' validations direcly within the model." do
|
450
450
|
lambda {
|
451
|
-
class Person < Sequel::Model
|
451
|
+
class Person < Sequel::Model
|
452
452
|
validations.clear
|
453
453
|
validates_length_of :first_name, :maximum => 30
|
454
454
|
end
|
@@ -457,7 +457,7 @@ describe Sequel::Model, "Validations" do
|
|
457
457
|
end
|
458
458
|
|
459
459
|
it "should define a has_validations? method which returns true if the model has validations, false otherwise" do
|
460
|
-
class Person < Sequel::Model
|
460
|
+
class Person < Sequel::Model
|
461
461
|
validations.clear
|
462
462
|
validates do
|
463
463
|
format_of :first_name, :with => /\w+/
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-01-
|
12
|
+
date: 2008-01-21 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -43,6 +43,7 @@ files:
|
|
43
43
|
- spec/rcov.opts
|
44
44
|
- spec/record_spec.rb
|
45
45
|
- spec/relations_spec.rb
|
46
|
+
- spec/relationships_spec.rb
|
46
47
|
- spec/schema_spec.rb
|
47
48
|
- spec/spec.opts
|
48
49
|
- spec/spec_helper.rb
|
@@ -55,6 +56,7 @@ files:
|
|
55
56
|
- lib/sequel_model/pretty_table.rb
|
56
57
|
- lib/sequel_model/record.rb
|
57
58
|
- lib/sequel_model/relations.rb
|
59
|
+
- lib/sequel_model/relationships.rb
|
58
60
|
- lib/sequel_model/schema.rb
|
59
61
|
- lib/sequel_model/validations.rb
|
60
62
|
- lib/sequel_model.rb
|