繁体   English   中英

引用Grails GORM中的参考表的域对象

[英]Domain object referring to a reference table in Grails GORM

我有一个名为User的域对象:

class User{
  String username;
  String firstName;
  String lastName;
  Zipcode zip;
}

我还有一个邮政编码对象:

class Zipcode {
  String zip;
  String city;
  String state;
  Float lat;
  Float long;
}

邮政编码表绝对不可修改,因为它包含预先填充的静态参考数据

用户属于一个邮政编码。 用户在用户创建过程中输入邮政编码。

我应该如何建模领域对象关系? 我想确保GORM不会尝试更新邮政编码。 我想确保用户仅输入有效的邮政编码。 (在邮政编码表中找到了哪些)我如何在User对象上配置约束? 在控制器中,我执行以下操作:

def userInstance = new User(params) // where params are form values

如何在对象上设置正确的邮政编码?

您根本不会让GORM管理zip属性(并限制GORM在第二阶段进行管理)。

这也是mfloryan的方法所说明的。 但是,他的方法不能正确地分离关注点关注点分离范例):在MVC (模型-视图-控制器)模式中,“建模”数据模型不是控制器的任务,而是模型的任务。数据访问层(如果是GORM,则是域自己进行分类)。

因此, User类将实现为:

class User {
    String userName
    String firstName
    String lastName
    String zip

    ZipCode retrieveZipCode() {
        ZipCode.findByZip(zip)
    }

static constraints = {
    zip nullable: false, blank: false, matches: /^\d{5}/,
    /* not tested at my machine: */
    validator: {
        if(!retrieveZipCode(it)) {
            return false
        }
    }
}
}

注意retrieveZipCode()方法。 它不称为getZipCode() ,否则,Hibernate将引发有关“缺少setter方法”的异常。 您还可以尝试添加zipCode属性, getZipCode()方法(不执行任何操作,或者抛出异常),然后将zipCode属性添加到transinients定义中。 -所有这些(任何组合)都将无法使用。

还要注意constraints定义:当zip正好由五位数字组成时,它会匹配。 (我相信这是美国那里的ZIP格式。)还应确保数据库包含用户的ZIP条目(未经测试的语法)。

我对ZipCode类进行了一些更改(部分是为了避免编译错误):

class ZipCode {
    String zip;
    String city;
    String state;
    Float latitude;
    Float longitude;
}

最后,有一个集成测试:

class UserTests extends GroovyTestCase {
    def testUserCreation() {
        User user = new User(
            userName: "foo", firstName: "bar", 
            lastName: "baz", zip: "12345")
        assert user.validate()
        assert user.retrieveZipCode()
        user.save()
    }
}

谢谢

这听起来更像是一个UI问题。 在控制器中执行Zipcode对象查找,并设置位于用户上的对象。 否则,我看不到在创建用户后如何更改Zipcode

save = {
  params.zip.id = Zipcode.findByZip(params.zip)
  def userInstance = new User(params)
}

要么

save = {
  def userInstance = new User(params)
  userInstance.zip = Zipcode.findByZip(params.zip) 
}

您应该包括一些验证逻辑(如果zip错误),并考虑将params.zip重命名为params.userProvidedZip或类似的名称。

使用域事件回调

   transient beforeUpdate = { 
      // check to make sure that the zip code value remains the same
      // and is never changed... 
   } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM