【问题标题】:Is there a way to create a relationship to an arbitraray domain object in grails有没有办法在 grails 中创建与任意域对象的关系
【发布时间】:2015-11-25 21:30:45
【问题描述】:

有没有办法在 grails 中创建与任意域对象的关联?

类似

class ThingHolder {
    DomainObject thing;
}

然后

Book b=new Book(title: "Grails 101").save()
Author a=new Author(name: "Abe").save()

ThingHolder t1=new ThingHolder(thing:b).save()
ThingHolder t2=new ThingHolder(thing: a).save()

这样

ThingHolder.get(t1.id).thing  // will be a Book

ThingHolder.get(t2.id).thing  // will be an Author.

【问题讨论】:

    标签: grails grails-orm


    【解决方案1】:

    我仍在寻找一种更简单的方法来做到这一点,但这似乎可以完成工作。

    class ThingHolder {
        static constraints = {
            thing bindable:true // required so 'thing' is bindable in default map constructor.
        }
    
        def grailsApplication;
    
        Object thing;
    
        String thingType;
        String thingId;
    
        void setThing(Object thing) {    //TODO: change Object to an interface
            this.thing=thing;
            this.thingType=thing.getClass().name
            this.thingId=thing.id;       //TODO: Grailsy way to get the id
        }
    
        def afterLoad() {
            def clazz=grailsApplication.getDomainClass(thingType).clazz
            thing=clazz.get(thingId);
        }
    }
    

    假设您有 Book 和 Author(不覆盖域对象的 ID 属性)。

    def thing1=new Author(name : "author").save(failOnError:true);
    def thing2=new Book(title: "Some book").save(failOnError:true);
    
    new ThingHolder(thing:thing1).save(failOnError:true)
    new ThingHolder(thing:thing2).save(failOnError:true)
    
    ThingHolder.list()*.thing.each { println it.thing }
    

    我在这两个答案中发现了一些非常有用的提示。

    How to make binding work in default constructor with transient values.

    How to generate a domain object by string representation of class name

    【讨论】:

      【解决方案2】:

      更新(基于评论)

      由于您不想(或不能)在域模型中扩展另一个类,因此使用 GORM 是不可能的。

      原始答案

      是的,您可以这样做。这叫继承。在您的情况下,您将拥有一个 Thing,它是 AuthorBook 的超类。

      您的域模型可能如下所示:

      class Thing {
        // anything that is common among things should be here
      }
      
      class Author extends Thing {
        // anything that is specific about an author should be here
      }
      
      class Book extends Thing {
        // anything that is specific about a book should be here
      }
      
      class ThingHolder {
        Thing thing
      }
      

      由于AuthorBook 都扩展了Thing,因此它们也被视为Thing

      但是,在不了解继承以及 Grails/GORM 如何对数据库中的数据建模的情况下执行此操作是短视的。您应该充分研究这些主题,以确保这确实是您想要的。

      【讨论】:

      • 目标是能够报道任何领域对象。我不想将系统中的每个域对象都存储在 Thing 表中,也不想必须设置 Table_per_hierarchy 并导致到处都是外连接。
      • 那么答案是否定的。你不能在 GORM 中这样做。
      • 感谢您的快速回答。我希望有一些魔法可以创建一个带有列 ID、thing_discriminator、thing_id 或类似内容的 Thing_holder 表。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-26
      • 2021-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多