sequel_model 0.3.2.1 → 0.3.3
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 +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
|