在Grails中,如何获得Spring Security用户的关系属性?

时间:2013-05-09 02:39:48

标签: grails spring-security grails-2.0

我正在使用Spring Security。假设我有User属于StoreStore有一个属性,用于确定是否有在线商店:

class Store {
    ...
    boolean isOnline
    ...
}

class User {
    ...
    def belongsTo = [ store: Store ]
    ...
}

在每个页面上显示的全局导航栏模板中,如果当前登录用户的Store在线购物,我想显示一个链接。我目前正在工具栏模板中使用此代码:

<g:set var="userId" value="${sec.loggedInUserInfo(field: 'id') as Long}"/>
<g:set var="user" value="${User.get(userId)}"/>

<g:if test="${user.store.isOnline}">
    <li>
        <g:link controller="store" action="redirect">Shop Online</g:link>
    </li>
</g:if>

虽然这段代码有效,但是有更好的方法来处理这个逻辑吗?我并不特别喜欢我正在为每个页面渲染执行此代码,我特别不喜欢我在视图中直接使用User.get()

换句话说,对于一个允许我抓住实际springSecurityService.currentUser对象并沿着它的关系传播的视图,是否有等同于User的内容?

3 个答案:

答案 0 :(得分:0)

您可以将此逻辑移至过滤器:

class UserFilters {

   SpringSecurityService springSecurityService

   def filters = {
       loadUser(controller: '*', action: '*') {
           before = {
              def user = springSecurityService.currentUser
              request.setAttribute('currentUser', user)
           }
       }
   }

}

因此,您可以在视图中使用currentUser

<g:if test="${currentUser.store.isOnline}">
  ...
</g:if>

有关过滤器的更多信息:http://grails.org/doc/latest/guide/theWebLayer.html#filters

答案 1 :(得分:0)

我建议将此逻辑移动到控制器并为该控制器准备视图(您用于导航栏的小块)。然后,您可以使用<g:include/>标记重用该视图的控制器操作。

答案 2 :(得分:0)

.get()通常会在点击数据库之前从二级缓存中提取,因此这不是我所关注的。逻辑的位置只是放错了地方。我会将您的视图逻辑放在自定义标记库中。