File: validate_associated_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 (85 lines) | stat: -rw-r--r-- 3,026 bytes parent folder | download | duplicates (2)
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
74
75
76
77
78
79
80
81
82
83
84
85
require_relative "spec_helper"

describe "ValidatesAssociated plugin" 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.plugin :validate_associated
    @c.columns :id, :name, :c_id
    @c.one_to_many :cs, :class=>@c, :key=>:c_id
    @o = @c.load(:id=>1, :name=>'a')
    @db.sqls
  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.load(:id=>2, :name=>'b')
    @o.send(:delay_validate_associated_object, @c.association_reflection(:cs), o)
    @o.save.must_be_nil
    @o.errors[:cs].must_equal ["name is b"]
    o.errors[:name].must_equal ['is b']
  end

  it "should support creating new one_to_many and one_to_one objects with presence validations on the foreign key" do
    @c.class_eval do
      plugin :validation_helpers
      def validate
        validates_presence :c_id
        errors.add([:name, :c_id], 'compound error') unless c_id
        super
      end
    end
    o = @c.new(:name=>'a', :c_id=>1)
    c = @c.new(:name=>'b')
    o.valid?.must_equal true
    c.valid?.must_equal false

    o.send(:delay_validate_associated_object, @c.association_reflection(:cs), c)
    o.valid?.must_equal true
    c.valid?.must_equal false
    @db.sqls.must_equal []

    o.save
    @db.sqls.must_equal ["INSERT INTO cs (name, c_id) VALUES ('a', 1)", "SELECT * FROM cs WHERE (id = 1) LIMIT 1"]
  end

  it "should handle other errors when validating" do
    @c.class_eval do
      plugin :validation_helpers
      def validate
        unless c_id
          validates_presence :id
          errors.add([:name, :id], 'compound error')
        end
        super
      end
    end
    o = @c.new(:name=>'a', :c_id=>1)
    c = @c.new(:name=>'b')
    o.valid?.must_equal true
    c.valid?.must_equal false

    o.send(:delay_validate_associated_object, @c.association_reflection(:cs), c)
    o.valid?.must_equal false
    o.errors.on(:cs).must_equal ["id is not present", "name and id compound error"]
    c.valid?.must_equal false
    @db.sqls.must_equal []
  end

  it "should should not remove existing values from object when validating" do
    o = @c.load(:id=>2, :name=>'b', :c_id=>3)
    @o.send(:delay_validate_associated_object, @c.association_reflection(:cs), o)
    @o.valid?.must_equal true
    o.c_id.must_equal 3
  end
  
  it "should not attempt to validate associated_object if the :validate=>false option is passed to save" do
    @c.one_to_many :cs, :class=>@c, :key=>:c_id
    @c.send(:define_method, :validate){|*| errors.add(:name, 'is b') if name == 'b'}
    o = @c.load(:id=>2, :name=>'b', :c_id=>3)
    @o.send(:delay_validate_associated_object, @c.association_reflection(:cs), o)
    @o.save(:validate=>false).must_equal @o
    @db.sqls.must_equal ["UPDATE cs SET name = 'a' WHERE (id = 1)"]
  end
end