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 CHANGED
@@ -1,3 +1,7 @@
1
+ === 0.3.3 (2008-01-25)
2
+
3
+ * Finalized support for virtual attributes.
4
+
1
5
  === 0.3.2.1 (2008-01-24)
2
6
 
3
7
  * Fixed Model.dataset to correctly set the dataset if using implicit naming or inheriting the superclass dataset (thanks celldee).
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ include FileUtils
9
9
  # Configuration
10
10
  ##############################################################################
11
11
  NAME = "sequel_model"
12
- VERS = "0.3.2.1"
12
+ VERS = "0.3.3"
13
13
  CLEAN.include ["**/.*.sw?", "pkg/*", ".config", "doc/*", "coverage/*"]
14
14
  RDOC_OPTS = [
15
15
  "--quiet",
@@ -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, true, &block)
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 = {}, new_record = false, &block)
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
- @new = new_record
193
- unless @new # determine if it's a new record
194
- k = self.class.primary_key
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
- #unless const_defined?(klass.to_s.camel_case)
105
- #raise Sequel::Error, "#{klass.to_s.camel_case} does not exist"
106
- #end
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
- # 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
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.db.dataset.left_outer_join(#{relation}, :id => :#{relation.to_s.singularize}_id).limit(1)
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.db.dataset.left_outer_join(#{relation}, :id => :#{relation.to_s.singularize}_id)
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
@@ -1,12 +1,191 @@
1
1
  require File.join(File.dirname(__FILE__), "spec_helper")
2
2
 
3
- __END__
3
+ #__END__
4
4
 
5
- describe Sequel::Model::Relationships, "has :one" do
6
- end
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
- describe Sequel::Model::Relationships, "has :many" do
9
- end
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
@@ -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 multple validations" do
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.2.1
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-24 00:00:00 +02:00
12
+ date: 2008-01-25 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency