File: delay_add_association_spec.rb

package info (click to toggle)
ruby-sequel 5.63.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 10,408 kB
  • sloc: ruby: 113,747; makefile: 3
file content (73 lines) | stat: -rw-r--r-- 2,695 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
require_relative "spec_helper"

describe "Sequel::Plugins::DelayAddAssociation" do
  before do
    @db = Sequel.mock(:autoid=>1, :numrows=>1, :fetch=>{:id=>1, :name=>'a', :c_id=>nil})
    @c = Class.new(Sequel::Model(@db[:cs]))
    @c.send(:define_method, :save){|*| super(:changed=>true)}
    @c.plugin :delay_add_association
    @c.columns :id, :name, :c_id
    @c.one_to_many :cs, :class=>@c, :key=>:c_id
    @db.sqls
  end

  it "should delay adding of the association until after creation" do
    @o = @c.new(:name=>'a')
    @o.add_c(@c.load(:id=>2, :name=>'b'))
    @db.sqls.must_equal []
    @o.save
    @db.sqls.must_equal ["INSERT INTO cs (name) VALUES ('a')", "SELECT * FROM cs WHERE (id = 1) LIMIT 1", "UPDATE cs SET c_id = 1 WHERE (id = 2)"]
  end

  it "should immediately reflect changes in cached association" do
    @o = @c.new(:name=>'a')
    o = @c.load(:id=>2, :name=>'b')
    @o.add_c(o)
    @o.cs.must_equal [o]
    @db.sqls.must_equal []
  end

  it "should not affect adding associations to existing rows" do
    @o = @c.load(:id=>1, :name=>'a')
    @o.add_c(@c.load(:id=>2, :name=>'b'))
    @db.sqls.must_equal ["UPDATE cs SET c_id = 1 WHERE (id = 2)"]
  end

  it "should raise an error when saving if the associated object is invalid" do
    @c.send(:define_method, :validate){|*| errors.add(:name, 'is b') if name == 'b'}
    @o = @c.new(:name=>'a')
    @o.add_c(@c.load(:id=>2, :name=>'b'))
    proc{@o.save}.must_raise Sequel::ValidationFailed
  end

  it "should return nil when saving if the associated object is invalid when raise_on_save_failure is false" do
    @c.raise_on_save_failure = false
    @c.send(:define_method, :validate){|*| errors.add(:name, 'is b') if name == 'b'}
    @o = @c.new(:name=>'a')
    @o.add_c(@c.load(:id=>2, :name=>'b'))
    @o.save.must_be_nil
    @o.errors[:cs].must_equal ["name is b"]
    @o.cs.first.errors[:name].must_equal ['is b']
  end

  it "should work when passing in hashes" do
    @o = @c.new(:name=>'a')
    @o.add_c(:name=>'b')
    @db.sqls.must_equal []
    @o.save
    @db.sqls.must_equal [
      "INSERT INTO cs (name) VALUES ('a')",
      "SELECT * FROM cs WHERE (id = 1) LIMIT 1",
      "INSERT INTO cs (name, c_id) VALUES ('b', 1)",
      "SELECT * FROM cs WHERE (id = 2) LIMIT 1"]
  end

  it "should work when passing in primary keys" do
    @db.fetch = [[{:id=>2, :name=>'b', :c_id=>nil}], [{:id=>1, :name=>'a', :c_id=>nil}]]
    @o = @c.new(:name=>'a')
    @o.add_c(2)
    @db.sqls.must_equal ["SELECT * FROM cs WHERE (id = 2) LIMIT 1"]
    @o.save
    @db.sqls.must_equal ["INSERT INTO cs (name) VALUES ('a')", "SELECT * FROM cs WHERE (id = 1) LIMIT 1", "UPDATE cs SET c_id = 1 WHERE (id = 2)"]
  end
end