sequel_model 0.3.3 → 0.4

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