sequel_model 0.3.2.1 → 0.3.3
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/record.rb +24 -6
- data/lib/sequel_model/relationships.rb +11 -20
- data/spec/record_spec.rb +9 -0
- data/spec/relationships_spec.rb +185 -6
- data/spec/validations_spec.rb +1 -1
- metadata +2 -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.3"
|
13
13
|
CLEAN.include ["**/.*.sw?", "pkg/*", ".config", "doc/*", "coverage/*"]
|
14
14
|
RDOC_OPTS = [
|
15
15
|
"--quiet",
|
data/lib/sequel_model/record.rb
CHANGED
@@ -129,7 +129,7 @@ module Sequel
|
|
129
129
|
# new? returns true.
|
130
130
|
def self.create(values = {}, &block)
|
131
131
|
db.transaction do
|
132
|
-
obj = new(values,
|
132
|
+
obj = new(values, &block)
|
133
133
|
obj.save
|
134
134
|
obj
|
135
135
|
end
|
@@ -185,13 +185,27 @@ module Sequel
|
|
185
185
|
#
|
186
186
|
# This method guesses whether the record exists when
|
187
187
|
# <tt>new_record</tt> is set to false.
|
188
|
-
def initialize(values =
|
189
|
-
@values = values || {}
|
188
|
+
def initialize(values = nil, from_db = false, &block)
|
190
189
|
@changed_columns = []
|
190
|
+
unless from_db
|
191
|
+
@values = {}
|
192
|
+
if values
|
193
|
+
values.each do |k, v| m = :"#{k}="
|
194
|
+
if respond_to?(m)
|
195
|
+
send(m, v)
|
196
|
+
values.delete(k)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
@values.merge!(values)
|
200
|
+
end
|
201
|
+
else
|
202
|
+
@values = values || {}
|
203
|
+
end
|
191
204
|
|
192
|
-
|
193
|
-
|
194
|
-
|
205
|
+
k = primary_key
|
206
|
+
if from_db
|
207
|
+
@new = k == nil
|
208
|
+
else
|
195
209
|
# if there's no primary key for the model class, or
|
196
210
|
# @values doesn't contain a primary key value, then
|
197
211
|
# we regard this instance as new.
|
@@ -202,6 +216,10 @@ module Sequel
|
|
202
216
|
after_initialize
|
203
217
|
end
|
204
218
|
|
219
|
+
def self.load(values)
|
220
|
+
new(values, true)
|
221
|
+
end
|
222
|
+
|
205
223
|
# Returns true if the current instance represents a new record.
|
206
224
|
def new?
|
207
225
|
@new
|
@@ -80,9 +80,8 @@ module Sequel
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
class << self
|
85
|
-
cattr_reader :model_relationships
|
86
85
|
@@model_relationships = []
|
87
86
|
|
88
87
|
def relationship_exists?(arity,relation)
|
@@ -97,21 +96,19 @@ module Sequel
|
|
97
96
|
# has :one, :account # account_id field
|
98
97
|
# has :many, :comments # comments_posts join table
|
99
98
|
def has(arity, klass, options = {})
|
99
|
+
|
100
|
+
# Commence with the sanity checks!
|
100
101
|
unless [:one,:many].include? arity
|
101
102
|
raise Sequel::Error, "Arity must be specified {:one, :many}."
|
102
103
|
end
|
103
104
|
|
104
|
-
|
105
|
-
|
106
|
-
|
105
|
+
if relationship_exists?(arity, klass)
|
106
|
+
raise Sequel::Error, "The relationship '#{self} has #{arity} #{klass}' is already defined."
|
107
|
+
end
|
107
108
|
|
108
109
|
# Make sure the join table exists
|
109
110
|
auto_create_join_table(klass, options)
|
110
111
|
|
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
112
|
# Store the relationship
|
116
113
|
@@model_relationships << {
|
117
114
|
:arity => arity,
|
@@ -200,17 +197,11 @@ module Sequel
|
|
200
197
|
def has_relationships?
|
201
198
|
model_relationships.length > 0 ? true : false
|
202
199
|
end
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
def snake_case
|
207
|
-
gsub(/\B[A-Z]/, '_\&').downcase
|
200
|
+
|
201
|
+
def model_relationships
|
202
|
+
@@model_relationships
|
208
203
|
end
|
209
204
|
|
210
|
-
# "foo_bar".camel_case #=> "FooBar"
|
211
|
-
def camel_case
|
212
|
-
split('_').map{|e| e.capitalize}.join
|
213
|
-
end
|
214
205
|
end
|
215
206
|
|
216
207
|
# Defines relationship method from the current class to the klass specified
|
@@ -218,13 +209,13 @@ module Sequel
|
|
218
209
|
if arity == :one
|
219
210
|
self.instance_eval "
|
220
211
|
def #{relation}
|
221
|
-
self.
|
212
|
+
self.dataset.left_outer_join(#{relation}, :id => :#{self.class.table_name.to_s.singularize}_id).limit(1)
|
222
213
|
end
|
223
214
|
"
|
224
215
|
elsif arity == :many
|
225
216
|
self.instance_eval "
|
226
217
|
def #{relation}
|
227
|
-
self.
|
218
|
+
self.dataset.left_outer_join(#{relation}, :id => :#{self.class.table_name.to_s.singularize}_id)
|
228
219
|
end
|
229
220
|
"
|
230
221
|
end
|
data/spec/record_spec.rb
CHANGED
@@ -476,6 +476,15 @@ describe Sequel::Model, "#initialize" do
|
|
476
476
|
m = @c.new {|o| o[:id] = 1234}
|
477
477
|
m.id.should == 1234
|
478
478
|
end
|
479
|
+
|
480
|
+
specify "should accept virtual attributes" do
|
481
|
+
@c.class_def(:blah=) {|x| @blah = x}
|
482
|
+
@c.class_def(:blah) {@blah}
|
483
|
+
|
484
|
+
m = @c.new(:id => 1, :x => 2, :blah => 3)
|
485
|
+
m.values.should == {:id => 1, :x => 2}
|
486
|
+
m.blah.should == 3
|
487
|
+
end
|
479
488
|
end
|
480
489
|
|
481
490
|
describe Sequel::Model, ".create" do
|
data/spec/relationships_spec.rb
CHANGED
@@ -1,12 +1,191 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
2
|
|
3
|
-
__END__
|
3
|
+
#__END__
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
# class Post < Sequel::Model
|
6
|
+
# relationships do
|
7
|
+
# has :one, :blog, :required => true, :normalized => false # uses a blog_id field, which cannot be null, in the Post model
|
8
|
+
# has :one, :account # uses a join table called accounts_posts to link the post with it's account.
|
9
|
+
# has :many, :comments # uses a comments_posts join table
|
10
|
+
# has :many, :authors, :required => true # authors_posts join table, requires at least one author
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
describe Sequel::Model, "relationships" do
|
14
|
+
before :all do
|
15
|
+
class Smurf < Sequel::Model
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
after :each do
|
20
|
+
Smurf.model_relationships.clear
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "has" do
|
24
|
+
|
25
|
+
it "should raise an exception if an arity {:one, :many} is not specified" do
|
26
|
+
Smurf.should_not_receive(:auto_create_join_table).with(:smurfette, {}).and_return(true)
|
27
|
+
Smurf.should_not_receive(:relationship_exists?).with(:one, :smurfette).and_return(true)
|
28
|
+
Smurf.stub!(:after_initialize)
|
29
|
+
lambda {
|
30
|
+
class Smurf
|
31
|
+
relationships do
|
32
|
+
has :sex, :with_smurfette
|
33
|
+
end
|
34
|
+
end
|
35
|
+
}.should raise_error Sequel::Error, "Arity must be specified {:one, :many}."
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should check to see if the relationship exists" do
|
39
|
+
Smurf.should_not_receive(:relationship_exists?).with(:one, :smurfette).and_return(true)
|
40
|
+
Smurf.stub!(:after_initialize)
|
41
|
+
lambda {
|
42
|
+
class Smurf
|
43
|
+
relationships do
|
44
|
+
has :sex, :with_smurfette
|
45
|
+
end
|
46
|
+
end
|
47
|
+
}.should raise_error Sequel::Error, "Arity must be specified {:one, :many}."
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should raise an exception if the relationship has already been specified" do
|
51
|
+
Smurf.should_receive(:relationship_exists?).with(:one, :smurfette).and_return(true)
|
52
|
+
Smurf.stub!(:after_initialize)
|
53
|
+
lambda {
|
54
|
+
class Smurf
|
55
|
+
relationships do
|
56
|
+
has :one, :smurfette
|
57
|
+
end
|
58
|
+
end
|
59
|
+
}.should raise_error Sequel::Error, "The relationship 'Smurf has one smurfette' is already defined."
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should establish a has :one relationship" do
|
63
|
+
Smurf.stub!(:auto_create_join_table)
|
64
|
+
Smurf.should_receive(:relationship_exists?).with(:one, :smurfette).and_return(false)
|
65
|
+
Smurf.should_receive(:after_initialize)
|
66
|
+
class Smurf
|
67
|
+
relationships do
|
68
|
+
has :one, :smurfette
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
@smurf = Smurf.new
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should establish a has :many relationship" do
|
77
|
+
Smurf.should_receive(:auto_create_join_table).with(:smurfette, {}).and_return(true)
|
78
|
+
Smurf.should_receive(:relationship_exists?).with(:many, :smurfette).and_return(false)
|
79
|
+
Smurf.should_receive(:after_initialize)
|
80
|
+
class Smurf
|
81
|
+
relationships do
|
82
|
+
has :many, :smurfette
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
@smurf = Smurf.new
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should call the auto_create_join_table method" do
|
90
|
+
Smurf.should_receive(:auto_create_join_table).with(:smurfette, {}).and_return(true)
|
7
91
|
|
8
|
-
|
9
|
-
|
92
|
+
class Smurf
|
93
|
+
relationships do
|
94
|
+
has :one, :smurfette
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should store the relationship to ensure there is no duplication" do
|
100
|
+
class Smurf
|
101
|
+
relationships do
|
102
|
+
has :one, :smurfette
|
103
|
+
has :many, :legs
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
Smurf.model_relationships.should == [
|
108
|
+
{:arity=>:one, :options=>{}, :klass=>:smurfette},
|
109
|
+
{:arity=>:many, :options=>{}, :klass=>:legs}
|
110
|
+
]
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should create an instance method for the has one relationship" do
|
115
|
+
class Smurf
|
116
|
+
relationships do
|
117
|
+
has :one, :smurfette
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
@smurf = Smurf.new
|
122
|
+
@smurf.should respond_to(:smurfette)
|
123
|
+
@smurf.should_not respond_to(:smurfettes)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should create an instance method for the has many relationship" do
|
127
|
+
class Smurf
|
128
|
+
relationships do
|
129
|
+
has :one, :smurfettes
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
@smurf = Smurf.new
|
134
|
+
@smurf.should respond_to(:smurfettes)
|
135
|
+
@smurf.should_not respond_to(:smurf)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe "has_one" do
|
140
|
+
it "should be an alias for has :one" do
|
141
|
+
Smurf.should_receive(:has).with(:one, :smurfette, {})
|
142
|
+
class Smurf
|
143
|
+
relationships do
|
144
|
+
has_one :smurfette
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "has_many" do
|
151
|
+
it "should be an alias for has :many" do
|
152
|
+
Smurf.should_receive(:has).with(:many, :smurfette, {})
|
153
|
+
class Smurf
|
154
|
+
relationships do
|
155
|
+
has_many :smurfette
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "belongs_to" do
|
162
|
+
it "should be an alias for has :one" do
|
163
|
+
Smurf.should_receive(:has).with(:one, :smurfette, {})
|
164
|
+
class Smurf
|
165
|
+
relationships do
|
166
|
+
belongs_to :smurfette
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "has_relationships?" do
|
173
|
+
it "should return true if the class has any relationships" do
|
174
|
+
class Smurf
|
175
|
+
relationships do
|
176
|
+
belongs_to :smurfette
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
Smurf.has_relationships?.should be_true
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should return false if the class has no relationships" do
|
184
|
+
class Smurf
|
185
|
+
end
|
186
|
+
|
187
|
+
Smurf.has_relationships?.should be_false
|
188
|
+
end
|
189
|
+
end
|
10
190
|
|
11
|
-
describe Sequel::Model::Relationships, "belongs_to" do
|
12
191
|
end
|
data/spec/validations_spec.rb
CHANGED
@@ -138,7 +138,7 @@ describe Sequel::Model, "Validations" do
|
|
138
138
|
@cow.should be_valid
|
139
139
|
end
|
140
140
|
|
141
|
-
it "should have a validates block that calls
|
141
|
+
it "should have a validates block that calls multiple validations" do
|
142
142
|
class Person < Sequel::Model
|
143
143
|
validations.clear
|
144
144
|
validates do
|
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: 0.3.
|
4
|
+
version: 0.3.3
|
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-25 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|