【问题标题】:Grails controllers dynamic findersGrails 控制器动态查找器
【发布时间】:2011-08-30 19:11:06
【问题描述】:

我对 Grails 有点陌生,所以我需要帮助解决这个问题。想象一下我有这些课程:

Class User{
String name
String nr

}

class Computer{

String processor
String ram
User user
}

Class Room{
String roomNr
Computer computer
}

我想做一个这样的控制器:

def print= {

        def user = User.get(1)

        def computer = Computer.findAllByUser(user) // all computers filtered by User

        [computer: computer]       
    }

控制器运行良好,但我希望不仅能够传递计算机实例,还能够传递具有该计算机 ID 的 Room。我不知道该怎么做,但会是这样的(相同的控制器,相同的动作):

定义打印= {

        def user = User.get(1)

        def computer = Computer.findAllByUser(user) // all computers filtered by User
        def room = Room.findAllByComputer(computer) ##

        [computer: computer]       
    }

嗯,这是错误的,因为在### 所在的位置,'computer' 表示 id 的列表,而不是单个 id。当我在 g 中传递要在 gsp 中打印的计算机列表时:每个标签都像这样:(它。处理器,它。Ram)。我不知道如何在每个标签中获取所有正在使用当前计算机的房间。这有点难以解释,但基本上我的输出是:

<g:each in="${computer}"
Computer1:
Processor: ${it.processor}
Ram: ${it.ram}
Room: ????? (How to get here??)
</g:each>

【问题讨论】:

    标签: grails controllers


    【解决方案1】:

    使关系双向。现在你存储了哪个房间有哪台计算机,但你不会反过来,所以你可以跟随一台计算机到它的房间。看看

    http://grails.org/doc/1.0.x/guide/5.%20Object%20Relational%20Mapping%20(GORM).html

    特别是第 5.2.1.2 节,关于双向一对多关系。

    请注意,Grails 是基于同类最佳技术构建的。其中之一是休眠。熟悉底层技术只会对您有所帮助。

    毕竟,我要说的是,您的计算机类应该引用它所在的房间。房间类应该有一个计算机列表(假设一个房间里可以有多台计算机) .您将遇到的困难在于理解 hibernate 的级联行为,这取决于您如何建立关系。如果您遇到问题,请更新此问题或针对特定问题开始新问题。

    【讨论】:

    • @Richard:我同意 hvgotcodes。返工域类后问题应该会消失。
    • 我认为这行不通,因为一个房间可以没有电脑。因此,如果我在房间表中有外键,我需要与计算机表建立关系。可以发生也可以不发生。
    • 必须有一种简单的方法来处理我当前的代码。有什么想法吗:P?
    • @richard,一个房间可以有多少台电脑? 0,1,或多于一个。没有房间,计算机可以存在吗?取消此答案的复选标记,直到解决为止。
    • 没有房间就不能存在计算机。一个房间可以有 0、1 ou + 电脑。
    【解决方案2】:

    我想出了类似的东西,但我没有测试它。

    控制器:

    def print = {
    
      def user = User.get(1)
      def computer = Computer.findAllByUser(user)
      def rooms = [:]
    
      // get rooms for that computer
      computer.each{
    
        def computerRooms = Room.findAllByComputer(it) // find all rooms where current computer is
        rooms.put(it.id, computerRooms) // map all the rooms with computer id
    
      }
    
      [computer: computer, rooms: rooms]      
    }
    

    查看:

    <g:each in="${computer}">
      Computer1:
      Processor: ${it.processor}
      Ram: ${it.ram}
      Rooms: <g:join in="${rooms[it.id]}" delimiter=", "/>
    </g:each>
    

    房间地图使用计算机 ID 作为键,并使用该计算机作为值的所有房间的列表。当然,如果我理解正确的话;)

    编辑

    如果您需要访问房间的详细信息,可以将join 标签替换为另一个each 标签,如下所示:

    <g:each in="${computer}" >
      Computer1:
      Processor: ${it.processor}
      Ram: ${it.ram}
      Rooms: <br/>
      <g:each in="${rooms[it.id]}">
        Room id: ${it.id}
        Room number: ${it.number}
      </g:each>
    </g:each>
    

    你也可以实现RoomtoString()方法,因为join标签使用它来渲染文本:

    Class Room{
      String roomNr
      ...
    
      String toString(){
        roomNr
      }
    }
    

    现在当你在Room类实例列表中使用join标签时,它会打印房间号。

    【讨论】:

    • 如何分别访问房间的每个属性?喜欢 it.roomNr 等等.. ?
    • 我喜欢这样: ?
    • 谢谢你:P 去试试吧 :p 但它似乎真的是我正在寻找的完美答案。
    【解决方案3】:

    看起来您没有将房间变量发送到视图

    [computer: computer]
    

    应该是:

    [computer:computer, room:room]
    

    【讨论】:

    • 大声笑是的,我知道 :P 但我需要通过计算机 ID 过滤房间。这就是问题所在,我不知道如何在控制器中做到这一点。
    【解决方案4】:

    您可以使用 在您的 中获取房间参考。这样,控制器就不关心房间了。一般来说,我喜欢收集控制器中提供 GSP 的所有相关信息,但也有例外,例如一些辅助细节。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多