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

发布于 2024-09-28 16:33:20 字数 564 浏览 4 评论 0原文

我有一个名为“用户”的域对象:

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

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

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

邮政编码表永远不应该被修改,因为它包含预填充的静态参考数据

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

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

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

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

I have a domain object called User:

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

I also have a Zip Code object:

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

The zipcode table should never be modified as it contains static reference data prepopulated

A user belongs to one zipcode. The user enters the zipcode as part of the User creation.

How should I model the domain objects relationship? I would like like to make sure that GORM does not attempt to update zipcodes. I would like to make sure that the user only enters valid zipcode numbers. (Which are found in the zipcode table) How do I configure the constraints on the User object? In the controller, I do the following:

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

How do I set the proper zipcode on the object?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

末蓝 2024-10-05 16:33:20

您根本不会让 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< /code> 属性到 transinients 定义。 - 所有这些(任何组合)都将不起作用

另请注意 constraints 定义:当 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()
    }
}

谢谢

You would not let GORM manage the zip property (and restrict GORM from doing so at a second stage), at all.

That's what mfloryan's approach tells, too; however, his approach doesn't separate concerns, properly (separation of concerns paradigm): In the MVC (Model-View-Controller) pattern, it's not the controllers' task to "model" the data model, but it's the task of the data access layer (which is - in case of GORM - the domain classes theirselves).

Thus, the User class would be implemented like that:

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
        }
    }
}
}

Note the retrieveZipCode() method. It's not called getZipCode() as, otherwise, Hibernate would throw an exception about a "missing setter method". You can also experiment with adding a zipCode property, a getZipCode() method (that does nothing or, alternatively, throws an exception), and adding the zipCode property to the transinients definition. - Everything of this (in any combination) will not work.

Also note the constraints definition: It matches when the zip consists of exactly five digits. (I believe that's the format of ZIP codes there in the USA.)
It should also make sure that the database contains an entry for the user's ZIP code (syntax not tested).

I've changed the ZipCode class slightly (partly, to avoid a compilation error):

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

And finally, there's an integration test:

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()
    }
}

Thanks

反话 2024-10-05 16:33:20

这听起来更像是一个用户界面问题。在控制器中执行 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 或类似的名称。

This sounds like more of an UI issue. Do a Zipcode object lookup in the controller and set the the object located on the user. Otherwise, I can't see how a Zipcode could have been altered upon creation of a user.

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

or

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

You should include some validation logic (if the zip is incorrect) and also consider renaming params.zip to params.userProvidedZip or something like that.

憧憬巴黎街头的黎明 2024-10-05 16:33:20

使用域事件回调

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

use Domain event callback

   transient beforeUpdate = { 
      // check to make sure that the zip code value remains the same
      // and is never changed... 
   } 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文