簡體   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