sequel_model 0.3.3 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ === 0.4 (2008-02-05)
2
+
3
+ * Fixed Model#set to work with string keys (#143).
4
+
5
+ * Fixed Model.create to correctly initialize instances marked as new (#135).
6
+
7
+ * Fixed Model#initialize to convert string keys into symbol keys. This also fixes problem with validating objects initialized with string keys (#136).
8
+
1
9
  === 0.3.3 (2008-01-25)
2
10
 
3
11
  * Finalized support for virtual attributes.
data/COPYING CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2006-2007 Sharon Rosner
1
+ Copyright (c) 2007-2008 Sharon Rosner
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ include FileUtils
9
9
  # Configuration
10
10
  ##############################################################################
11
11
  NAME = "sequel_model"
12
- VERS = "0.3.3"
12
+ VERS = "0.4"
13
13
  CLEAN.include ["**/.*.sw?", "pkg/*", ".config", "doc/*", "coverage/*"]
14
14
  RDOC_OPTS = [
15
15
  "--quiet",
@@ -117,7 +117,7 @@ require "spec/rake/spectask"
117
117
 
118
118
  desc "Run specs with coverage"
119
119
  Spec::Rake::SpecTask.new("spec") do |t|
120
- t.spec_files = FileList["spec/*_spec.rb"]
120
+ t.spec_files = FileList["spec/**/*_spec.rb"]
121
121
  t.spec_opts = File.read("spec/spec.opts").split("\n")
122
122
  t.rcov_opts = File.read("spec/rcov.opts").split("\n")
123
123
  t.rcov = true
@@ -125,7 +125,7 @@ end
125
125
 
126
126
  desc "Run specs without coverage"
127
127
  Spec::Rake::SpecTask.new("spec_no_cov") do |t|
128
- t.spec_files = FileList["spec/*_spec.rb"]
128
+ t.spec_files = FileList["spec/**/*_spec.rb"]
129
129
  t.spec_opts = File.read("spec/spec.opts").split("\n")
130
130
  end
131
131
 
@@ -171,7 +171,9 @@ module Sequel
171
171
  @primary_key ||= self.class.primary_key
172
172
  end
173
173
 
174
- # Returns the primary key value identifying the model instance. Stock implementation.
174
+ # Returns the primary key value identifying the model instance. If the
175
+ # model's primary key is changed (using #set_primary_key or #no_primary_key)
176
+ # this method is redefined accordingly.
175
177
  def pk
176
178
  @pk ||= @values[:id]
177
179
  end
@@ -196,26 +198,22 @@ module Sequel
196
198
  values.delete(k)
197
199
  end
198
200
  end
199
- @values.merge!(values)
201
+ values.inject(@values) {|m, kv| m[kv[0].to_sym] = kv[1]; m}
202
+ # @values.merge!(values)
200
203
  end
201
204
  else
202
205
  @values = values || {}
203
206
  end
204
207
 
205
208
  k = primary_key
206
- if from_db
207
- @new = k == nil
208
- else
209
- # if there's no primary key for the model class, or
210
- # @values doesn't contain a primary key value, then
211
- # we regard this instance as new.
212
- @new = (k == nil) || (!(Array === k) && !@values[k])
213
- end
209
+ @new = !from_db
214
210
 
215
211
  block[self] if block
216
212
  after_initialize
217
213
  end
218
214
 
215
+ # Initializes a model instance as an existing record. This constructor is
216
+ # used by Sequel to initialize model instances when fetching records.
219
217
  def self.load(values)
220
218
  new(values, true)
221
219
  end
@@ -272,8 +270,9 @@ module Sequel
272
270
 
273
271
  # Updates and saves values to database from the passed-in Hash.
274
272
  def set(values)
275
- this.update(values)
276
- values.each {|k, v| @values[k] = v}
273
+ v = values.inject({}) {|m, kv| m[kv[0].to_sym] = kv[1]; m}
274
+ this.update(v)
275
+ v.each {|k, v| @values[k] = v}
277
276
  end
278
277
  alias_method :update, :set
279
278
 
@@ -1,4 +1,6 @@
1
- gem 'assistance', '>= 0.1.2' # because we need Validations
1
+ gem "assistance", ">= 0.1.2" # because we need Validations
2
+
3
+ require "assistance"
2
4
 
3
5
  module Sequel
4
6
  class Model
data/lib/sequel_model.rb CHANGED
@@ -213,7 +213,7 @@ module Sequel
213
213
  # primary_key :id
214
214
  # text :title
215
215
  # text :category
216
- # foreign_key :author_id, :table => authors
216
+ # foreign_key :author_id, :table => :authors
217
217
  # end
218
218
  # end
219
219
  #
data/spec/hooks_spec.rb CHANGED
@@ -179,7 +179,7 @@ describe "Model#before_update && Model#after_update" do
179
179
  end
180
180
 
181
181
  specify "should be called around record update" do
182
- m = @c.new(:id => 2233)
182
+ m = @c.load(:id => 2233)
183
183
  m.save
184
184
  MODEL_DB.sqls.should == [
185
185
  'BLAH before',
@@ -200,7 +200,7 @@ describe "Model#before_save && Model#after_save" do
200
200
  end
201
201
 
202
202
  specify "should be called around record update" do
203
- m = @c.new(:id => 2233)
203
+ m = @c.load(:id => 2233)
204
204
  m.save
205
205
  MODEL_DB.sqls.should == [
206
206
  'BLAH before',
data/spec/model_spec.rb CHANGED
@@ -128,7 +128,7 @@ describe Sequel::Model, "new" do
128
128
  o.save
129
129
  o.id.should == 1234
130
130
 
131
- o = @m.new(:x => 1, :id => 333)
131
+ o = @m.load(:x => 1, :id => 333)
132
132
  o.save
133
133
  o.id.should == 333
134
134
  end
data/spec/record_spec.rb CHANGED
@@ -20,7 +20,7 @@ describe "Model#save" do
20
20
  end
21
21
 
22
22
  it "should update a record for an existing model instance" do
23
- o = @c.new(:id => 3, :x => 1)
23
+ o = @c.load(:id => 3, :x => 1)
24
24
  o.save
25
25
 
26
26
  MODEL_DB.sqls.first.should =~
@@ -28,7 +28,7 @@ describe "Model#save" do
28
28
  end
29
29
 
30
30
  it "should update only the given columns if given" do
31
- o = @c.new(:id => 3, :x => 1, :y => nil)
31
+ o = @c.load(:id => 3, :x => 1, :y => nil)
32
32
  o.save(:y)
33
33
 
34
34
  MODEL_DB.sqls.first.should == "UPDATE items SET y = NULL WHERE (id = 3)"
@@ -63,10 +63,15 @@ describe "Model#save_changes" do
63
63
  o.save_changes
64
64
 
65
65
  MODEL_DB.sqls.should be_empty
66
+
67
+ o = @c.load(:id => 3, :x => 1, :y => nil)
68
+ o.save_changes
69
+
70
+ MODEL_DB.sqls.should be_empty
66
71
  end
67
72
 
68
73
  it "should update only changed columns" do
69
- o = @c.new(:id => 3, :x => 1, :y => nil)
74
+ o = @c.load(:id => 3, :x => 1, :y => nil)
70
75
  o.x = 2
71
76
 
72
77
  o.save_changes
@@ -111,6 +116,14 @@ describe "Model#set" do
111
116
  o.x.should == 1
112
117
  end
113
118
 
119
+ it "should support string keys" do
120
+ o = @c.new(:id => 1)
121
+ o.x.should be_nil
122
+ o.set('x' => 1)
123
+ o.x.should == 1
124
+ MODEL_DB.sqls.first.should == "UPDATE items SET x = 1 WHERE (id = 1)"
125
+ end
126
+
114
127
  it "should be aliased by #update" do
115
128
  o = @c.new(:id => 1)
116
129
  o.update(:x => 1)
@@ -291,7 +304,7 @@ describe Sequel::Model, "update_with_params" do
291
304
  def self.columns; [:x, :y]; end
292
305
  end
293
306
  @o1 = @c.new
294
- @o2 = @c.new(:id => 5)
307
+ @o2 = @c.load(:id => 5)
295
308
  end
296
309
 
297
310
  it "should filter the given params using the model columns" do
@@ -485,6 +498,11 @@ describe Sequel::Model, "#initialize" do
485
498
  m.values.should == {:id => 1, :x => 2}
486
499
  m.blah.should == 3
487
500
  end
501
+
502
+ specify "should convert string keys into symbol keys" do
503
+ m = @c.new('id' => 1, 'x' => 2)
504
+ m.values.should == {:id => 1, :x => 2}
505
+ end
488
506
  end
489
507
 
490
508
  describe Sequel::Model, ".create" do
@@ -517,6 +535,13 @@ describe Sequel::Model, ".create" do
517
535
  o2.should == :blah
518
536
  MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (333)", "SELECT * FROM items WHERE (id IN ('INSERT INTO items (x) VALUES (333)')) LIMIT 1"]
519
537
  end
538
+
539
+ it "should create a row for a model with custom primary key" do
540
+ @c.set_primary_key :x
541
+ o = @c.create(:x => 30)
542
+ o.class.should == @c
543
+ MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (30)", "SELECT * FROM items WHERE (x = 30) LIMIT 1"]
544
+ end
520
545
  end
521
546
 
522
547
  describe Sequel::Model, "#refresh" do
@@ -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 multiple validations" do
141
+ it "should have a validates block that contains multiple validations" do
142
142
  class Person < Sequel::Model
143
143
  validations.clear
144
144
  validates do
@@ -182,6 +182,18 @@ describe Sequel::Model, "Validations" do
182
182
  Person.should have_validations
183
183
  Smurf.should_not have_validations
184
184
  end
185
+
186
+ it "should validate correctly instances initialized with string keys" do
187
+ class Can < Sequel::Model
188
+ def columns; [:id, :name]; end
189
+
190
+ validates_length_of :name, :minimum => 4
191
+ end
192
+
193
+ Can.new('name' => 'ab').should_not be_valid
194
+ Can.new('name' => 'abcd').should be_valid
195
+ end
196
+
185
197
  end
186
198
 
187
199
  describe "Model#save!" do
@@ -193,7 +205,7 @@ describe "Model#save!" do
193
205
  o.errors[a] << 'blah' unless v == 5
194
206
  end
195
207
  end
196
- @m = @c.new(:id => 4)
208
+ @m = @c.load(:id => 4)
197
209
  MODEL_DB.reset
198
210
  end
199
211
 
@@ -204,7 +216,7 @@ describe "Model#save!" do
204
216
  end
205
217
  end
206
218
 
207
- describe "Model#save!" do
219
+ describe "Model#save" do
208
220
  setup do
209
221
  @c = Class.new(Sequel::Model(:people)) do
210
222
  def columns; [:id]; end
@@ -213,7 +225,7 @@ describe "Model#save!" do
213
225
  o.errors[a] << 'blah' unless v == 5
214
226
  end
215
227
  end
216
- @m = @c.new(:id => 4)
228
+ @m = @c.load(:id => 4)
217
229
  MODEL_DB.reset
218
230
  end
219
231
 
@@ -224,7 +236,7 @@ describe "Model#save!" do
224
236
 
225
237
  @m.id = 5
226
238
  @m.should be_valid
227
- @m.save
239
+ @m.save.should_not be_false
228
240
  MODEL_DB.sqls.should == ['UPDATE people SET id = 5 WHERE (id = 5)']
229
241
  end
230
242
 
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.3
4
+ version: "0.4"
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-25 00:00:00 +02:00
12
+ date: 2008-02-05 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -44,30 +44,28 @@ files:
44
44
  - COPYING
45
45
  - README
46
46
  - Rakefile
47
+ - spec/hooks_spec.rb
47
48
  - spec/base_spec.rb
48
49
  - spec/caching_spec.rb
49
- - spec/hooks_spec.rb
50
- - spec/model_spec.rb
51
- - spec/plugins_spec.rb
52
- - spec/rcov.opts
50
+ - spec/validations_spec.rb
53
51
  - spec/record_spec.rb
52
+ - spec/spec_helper.rb
53
+ - spec/model_spec.rb
54
54
  - spec/relations_spec.rb
55
- - spec/relationships_spec.rb
56
55
  - spec/schema_spec.rb
56
+ - spec/rcov.opts
57
+ - spec/plugins_spec.rb
57
58
  - spec/spec.opts
58
- - spec/spec_helper.rb
59
- - spec/validations_spec.rb
60
59
  - lib/sequel_model
61
- - lib/sequel_model/base.rb
62
- - lib/sequel_model/caching.rb
63
- - lib/sequel_model/hooks.rb
64
- - lib/sequel_model/plugins.rb
60
+ - lib/sequel_model/validations.rb
65
61
  - lib/sequel_model/pretty_table.rb
66
62
  - lib/sequel_model/record.rb
67
63
  - lib/sequel_model/relations.rb
68
- - lib/sequel_model/relationships.rb
69
64
  - lib/sequel_model/schema.rb
70
- - lib/sequel_model/validations.rb
65
+ - lib/sequel_model/plugins.rb
66
+ - lib/sequel_model/hooks.rb
67
+ - lib/sequel_model/base.rb
68
+ - lib/sequel_model/caching.rb
71
69
  - lib/sequel_model.rb
72
70
  - CHANGELOG
73
71
  has_rdoc: true
@@ -1,224 +0,0 @@
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
- @@model_relationships = []
86
-
87
- def relationship_exists?(arity,relation)
88
- @@model_relationships.detect do |relation|
89
- relation[:arity] == arity &&
90
- relation[:klass] == relation
91
- end
92
- end
93
-
94
- # has arity<Symbol>, model<Symbol>
95
- # has :one, :blog, :required => true # blog_id field, cannot be null
96
- # has :one, :account # account_id field
97
- # has :many, :comments # comments_posts join table
98
- def has(arity, klass, options = {})
99
-
100
- # Commence with the sanity checks!
101
- unless [:one,:many].include? arity
102
- raise Sequel::Error, "Arity must be specified {:one, :many}."
103
- end
104
-
105
- if relationship_exists?(arity, klass)
106
- raise Sequel::Error, "The relationship '#{self} has #{arity} #{klass}' is already defined."
107
- end
108
-
109
- # Make sure the join table exists
110
- auto_create_join_table(klass, options)
111
-
112
- # Store the relationship
113
- @@model_relationships << {
114
- :arity => arity,
115
- :klass => klass,
116
- :options => options
117
- }
118
-
119
- # Define relationship methods
120
- after_initialize do
121
- define_relationship_method arity, klass, options
122
- end
123
-
124
- #unless normalized
125
- # :required => true # The relationship must be populated to save
126
- # can only be used with normalized => false :
127
- #end
128
- # save the relationship
129
- end
130
-
131
- # the proxy methods has_xxx ... , simply pass thru to to has :xxx, ...
132
- def has_one(klass, options = {})
133
- has :one, klass, options
134
- end
135
-
136
- def has_many(klass, options = {})
137
- has :many, klass, options
138
- end
139
-
140
- def belongs_to(klass, options = {})
141
- has :one, klass, options
142
- end
143
-
144
- # returns true if exists, false if not
145
- def join_table?(first, second)
146
- # we still have to test this out
147
- db[join_table(first, second)].table_exists?
148
- end
149
-
150
- # TODO: Move this elsewhere? outside relationships?
151
- # creates a join table given two table names
152
- def create_join_table(first, second)
153
- first_key, second_key = "#{first}_id", "#{second}_id"
154
- db.create_table join_table(first, second).to_sym do
155
- #primary_key [first_key.to_sym, second_key.to_sym]
156
- integer first_key, :null => false
157
- integer second_key, :null => false
158
- end unless join_table?(first, second)
159
- end
160
-
161
- def create_join_table!(first, second)
162
- db.drop_table join_table(first, second)
163
- create_join_table(first, second)
164
- end
165
-
166
- def auto_create_join_table!(klass)
167
- auto_create_join_table(klass, :force => true)
168
- end
169
-
170
- def auto_create_join_table(klass, options = {})
171
- first, second = table_name, klass.to_s.pluralize
172
- if join_table?(first, second) && options[:force] == true
173
- create_join_table!(first, second)
174
- else
175
- create_join_table(first, second)
176
- end
177
- end
178
-
179
- # Given two models, it outputs the join table name
180
- # which is sorted alphabetically with each table name pluralized
181
- # Examples:
182
- # join_table(user, post) #=> :posts_users
183
- # join_table(users, posts) #=> :posts_users
184
- def join_table(first, second)
185
- first, second = first.to_s.pluralize, second.to_s.pluralize
186
- [first, second].sort.join("_").to_sym
187
- end
188
-
189
- # relationships do
190
- # ...
191
- # end
192
- def relationships(&block)
193
- Relationships::Generator.new(self, &block)
194
- end
195
-
196
- # return true if there are validations stored, false otherwise
197
- def has_relationships?
198
- model_relationships.length > 0 ? true : false
199
- end
200
-
201
- def model_relationships
202
- @@model_relationships
203
- end
204
-
205
- end
206
-
207
- # Defines relationship method from the current class to the klass specified
208
- def define_relationship_method(arity, relation, options)
209
- if arity == :one
210
- self.instance_eval "
211
- def #{relation}
212
- self.dataset.left_outer_join(#{relation}, :id => :#{self.class.table_name.to_s.singularize}_id).limit(1)
213
- end
214
- "
215
- elsif arity == :many
216
- self.instance_eval "
217
- def #{relation}
218
- self.dataset.left_outer_join(#{relation}, :id => :#{self.class.table_name.to_s.singularize}_id)
219
- end
220
- "
221
- end
222
- end # define_relationship_method
223
- end # Model
224
- end # Sequel
@@ -1,191 +0,0 @@
1
- require File.join(File.dirname(__FILE__), "spec_helper")
2
-
3
- #__END__
4
-
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)
91
-
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
190
-
191
- end