常见域列的Mixin常见的beforeInsert和beforeUpdate方法

时间:2015-01-14 23:18:46

标签: grails groovy gorm mixins

我们公司使用的大多数域对象都有一些共同的属性。它们代表创建对象的用户,最后更新对象的用户以及他们用来执行该操作的程序。

为了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方法实际上没有被触发。

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

2 个答案:

答案 0 :(得分:5)

仅供参考,强烈建议不要使用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版本。

答案 1 :(得分:2)

您可以使用Grails Platform plugin事件总线代替mixins,让您的应用更加干净。该插件支持向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. 
}