【问题标题】:Common beforeInsert and beforeUpdate methods from Mixin for common domain columnsMixin 中用于公共域列的常见 beforeInsert 和 beforeUpdate 方法
【发布时间】:2015-03-13 07:19:55
【问题描述】:

我们公司使用的大多数域对象都有一些共同的属性。这些代表创建对象的用户、上次更新对象的用户以及他们用来执行此操作的程序。

为了DRY退出我的域类,我想找到一些方法将相同的 beforeInsert 和 beforeUpdate 逻辑添加到所有具有这些列的域类,而不会干扰那些没有这些列的域类。

我希望 喜欢 的方法是使用 Mixin 及其自己的 beforeInsert 和 beforeUpdate 方法。我知道you can use Mixins on domain classes

package my.com

import my.com.DomainMixin

@Mixin(DomainMixin)
class MyClass {
    String foo
    String creator
    String updater

    static constraints = {
        creator nullable:false
        updater nullable:false
    }
}


package my.com
class DomainMixin {
    def beforeInsert() {
        this.creator = 'foo'
        this.updater = 'foo'
    }

    def beforeUpdate() {
        this.updater = 'bar'
    }
}

单元测试表明,当以这种方式实现时, beforeInsert 方法实际上并没有被触发。

旁注: 我也知道to add the methods in a BootStrap.groovy file 可以使用metaClass,但是我的好奇心已经控制了我,我真的很想看看mixin 是否有效。随意告诉我,这是更好的方法,我不应该在人不应该的地方混淆。

【问题讨论】:

    标签: grails groovy grails-orm mixins


    【解决方案1】:

    仅供参考,强烈建议不要使用groovy.lang.Mixin(例如,Groovy 项目负责人)。如果你必须使用 mixins,你应该使用 grails.util.Mixin 代替。我不喜欢您的 mixin 方法的一件事是隐含且未强制执行的假设,即 mixin 的目标具有 creatorupdater 属性

    就个人而言,我可能会为此使用普通的继承,例如

    abstract class Audit {
    
        String creator
        String updater
    
        def beforeInsert() {
            this.creator = 'foo'
            this.updater = 'foo'
        }
    
        def beforeUpdate() {
            this.updater = 'bar'
        }
    
        static constraints = {
            creator nullable: false
            updater nullable: false
        }
    }
    

    任何需要审计的域类都可以简单地扩展Audit。另一种(也是更可取的)方法是使用 trait 而不是抽象基类,但您需要使用相当新的 Grails 版本才能做到这一点。

    【讨论】:

    • 继承对我来说似乎是合理的。我只需将 src/groovy 中的 mixin 更改为抽象类并使用扩展。我很想使用特征,但我们还没有完全掌握最新的 Grails。另外,我在编辑中注意到了这一点,但要使其正常工作,您需要一个 beforeValidate() 方法来填充所需字段的创建者和更新者,或者永远不会调用 beforeInsert 和 beforeUpdate。
    • 作为一个更新,继承在单元测试领域产生了一些我尚未解决的问题......主要是因为这里的示例隐藏了我实际实现的复杂性。见stackoverflow.com/questions/28048179/…
    • 来自上述链接的总结:Groovy 的@Delegate 方法就是答案。我想 Traits 会更漂亮,但现在,我很高兴使用 @Delegate 注释引入一个带有 beforeValidate 方法的类。
    【解决方案2】:

    您可以使用 Grails Platform pluginEvent Bus 来代替 mixins,以使您的应用更加 DRY。该插件支持向GORM events 添加侦听器,它们可以应用于任何给定的类或接口实例。您还可以附加多个监听器并编写更简洁的单元测试。

    如果你想跨域共享一些逻辑,它们必须实现一个接口,然后使用以下方法创建一个服务:

    // domainService.groovy
    
    @grails.events.Listener(namespace='gorm')
    def beforeInsert(DomainInterface domain){
        domain.creator = 'foo'
        domain.updater = 'bar'
    
        // If the method returns false, then domain.save() won't be called. 
    }
    

    【讨论】:

      猜你喜欢
      • 2012-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-06
      • 1970-01-01
      • 2022-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多