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 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