@@ -609,3 +609,96 @@ func TestPropagateUnscoped(t *testing.T) {
609
609
t .Fatalf ("unscoped did not propagate" )
610
610
}
611
611
}
612
+
613
+ type Product7 struct {
614
+ gorm.Model
615
+ Code string
616
+ Price float64
617
+ BeforeFindCallTimes int64 `gorm:"-"`
618
+ }
619
+
620
+ func (s * Product7 ) BeforeFind (tx * gorm.DB ) error {
621
+ s .BeforeFindCallTimes ++
622
+ return nil
623
+ }
624
+
625
+ // Modifies transient field
626
+ func TestBeforeFindHookCallCount (t * testing.T ) {
627
+ DB .Migrator ().DropTable (& Product7 {})
628
+ DB .AutoMigrate (& Product7 {})
629
+
630
+ p := Product7 {Code : "before_find_count" , Price : 100 }
631
+ DB .Save (& p )
632
+
633
+ var result Product7
634
+
635
+ DB .First (& result , "code = ?" , "before_find_count" )
636
+ if result .BeforeFindCallTimes != 1 {
637
+ t .Errorf ("Expected 1, got %d" , result .BeforeFindCallTimes )
638
+ }
639
+
640
+ DB .First (& result , "code = ?" , "before_find_count" )
641
+ if result .BeforeFindCallTimes != 2 {
642
+ t .Errorf ("Expected 2, got %d" , result .BeforeFindCallTimes )
643
+ }
644
+ }
645
+
646
+ type Product8 struct {
647
+ gorm.Model
648
+ Code string
649
+ Price float64
650
+ }
651
+
652
+ func (s * Product8 ) BeforeFind (tx * gorm.DB ) error {
653
+ tx .Statement .Where ("price > ?" , 50 )
654
+
655
+ return nil
656
+ }
657
+
658
+ // Fails for postgres
659
+ // ERROR: invalid input syntax for type bigint: "t" (SQLSTATE 22P02)
660
+ func TestBeforeFindModifiesQuery (t * testing.T ) {
661
+ DB .Migrator ().DropTable (& Product8 {})
662
+ DB .AutoMigrate (& Product8 {})
663
+
664
+ products := []Product8 {
665
+ {Code : "A" , Price : 100 },
666
+ {Code : "B" , Price : 30 },
667
+ }
668
+ DB .Create (& products )
669
+
670
+ var results []Product8
671
+
672
+ // Without condition, hooks will be skipped
673
+ DB .Find (& results , true )
674
+
675
+ if len (results ) != 1 || results [0 ].Code != "A" {
676
+ t .Errorf ("BeforeFind should filter results, got %v" , results )
677
+ }
678
+ }
679
+
680
+ type Product9 struct {
681
+ gorm.Model
682
+ Code string
683
+ Price float64
684
+ }
685
+
686
+ func (s * Product9 ) BeforeFind (tx * gorm.DB ) error {
687
+ s .Price = 200
688
+ return nil
689
+ }
690
+
691
+ func TestDatabaseOverwritesBeforeFindChanges (t * testing.T ) {
692
+ DB .Migrator ().DropTable (& Product9 {})
693
+ DB .AutoMigrate (& Product9 {})
694
+
695
+ p := Product9 {Code : "price_overwrite" , Price : 100 }
696
+ DB .Save (& p )
697
+
698
+ var result Product9
699
+ DB .First (& result , "code = ?" , "price_overwrite" )
700
+
701
+ if result .Price != 100 {
702
+ t .Errorf ("Price should be loaded from database, got %f" , result .Price )
703
+ }
704
+ }
0 commit comments