Grails - 无法在null对象上获取属性“id”

时间:2017-01-22 11:22:04

标签: grails parameters parameter-passing

这是我有一些问题。

我有2个域类,我想将一些参数从一个域类传递到第二个域类,并保存在第二个域类中。

这是第一个域类Car

package carrentco

class Car {

    String brand
    String model
    String fuelType
    BigDecimal pricePerDay

    static constraints = {
        brand(inList:["AUDI", "BMW", "MERCEDES", "NISSAN", "HONDA", "FORD"])
        model()
        fuelType(inList:["FUEL", "DIESEL", "AUTOGAS"])
        pricePerDay(min:0.0, max:1000.0)

    }
}

这是第二次注册

package carrentco

class Registration {

    String firstName
    String lastName
    Date dateOfBirth
    String phoneNumber
    String email
    Date startOfRentDate
    Date endOfRentDate
    Car rentedCar

    static constraints = {
        firstName(nullable: false)
        lastName(nullable: false)
        dateOfBirth()
        phoneNumber(phoneNumber: true, nullable: false)
        email(blank:false, email:true)
        startOfRentDate()
        endOfRentDate()
    }
}

我想做什么;我创建了一些汽车列表,我添加到cars / index.gsp每个汽车的一些按钮(RENT CAR)当用户点击这个按钮他去注册/ create.gsp这里用户添加一些自己的详细信息,如名字姓氏等我想要到达这里Car id自动从car / index.gsp中选择哪一个并保存此表单。当管理员查看此注册记录时,他将看到哪个汽车用户想要租用。

这是我的汽车/ index.gsp

 <g:each in="${carList}" var="car">
                <p>${car.id} </p>
                <g:link action="create" controller="registration" params="${[carId : car.id ]}">
                    Rent Car
                </g:link>

            </g:each>

这是我的注册/ create.gsp

<g:form action="save">
    <div><p>Car ID : ${car.id} </p></div>
    <fieldset class="form">
        <f:all bean="registration"/>
    </fieldset>
    <fieldset class="buttons">
        <input type="hidden" name="carId" id="carId" value="${car?.id}"/>
        <input type="text" name="yourName" required>
        <g:submitButton name="create" class="save" value="${message(code: 'default.button.create.label', default: 'Create')}" />
    </fieldset>
</g:form>

当我编写此代码时,我收到此错误,

URI
/registration/create
Class
java.lang.NullPointerException
Message
Request processing failed; nested exception is org.grails.gsp.GroovyPagesException: Error processing GroovyPageView: [views/registration/create.gsp:38] Error executing tag <g:form>: Error evaluating expression [car.id] on line [29]: Cannot get property 'id' on null object
Caused by
Cannot get property 'id' on null object

当我在registration / create.gsp

中尝试这个时
 <g:form action="save">
                <fieldset class="form">
                    <f:all bean="registration"/>
                </fieldset>
                <fieldset class="buttons">
                    <g:submitButton name="create" class="save" value="${message(code: 'default.button.create.label', default: 'Create')}" />
                </fieldset>
            </g:form>

一切都很好。我可以使用车辆ID保存注册表格,但在这里我需要从列表中选择哪个车辆ID。所以我不想要这个我希望这是自动选择,因为如果我点击从汽车列表示例汽车id 2租用汽车按钮为什么我需要再次在注册表中选择汽车ID它是不好的。

这是我的注册控制器。

package carrentco

import static org.springframework.http.HttpStatus.*
import grails.transaction.Transactional

@Transactional(readOnly = true)
class RegistrationController {

    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond Registration.list(params), model:[registrationCount: Registration.count()]
    }

    def show(Registration registration) {
        respond registration
    }

    def create() {
        respond new Registration(params)
        def selectedCar = Car.get(params.carId)
        [car: selectedCar]
    }

    @Transactional
    def save(Registration registration) {

        if (registration == null) {
            transactionStatus.setRollbackOnly()
            notFound()
            return

        }

        if (registration.hasErrors()) {
            transactionStatus.setRollbackOnly()
            respond registration.errors, view:'create'
            return
        }

        registration.save flush:true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [message(code: 'registration.label', default: 'Registration'), registration.id])
                redirect registration
            }
            '*' { respond registration, [status: CREATED] }
        }
    }

    def edit(Registration registration) {
        respond registration
    }

    @Transactional
    def update(Registration registration) {
        if (registration == null) {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (registration.hasErrors()) {
            transactionStatus.setRollbackOnly()
            respond registration.errors, view:'edit'
            return
        }

        registration.save flush:true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'registration.label', default: 'Registration'), registration.id])
                redirect registration
            }
            '*'{ respond registration, [status: OK] }
        }
    }

    @Transactional
    def delete(Registration registration) {

        if (registration == null) {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        registration.delete flush:true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'registration.label', default: 'Registration'), registration.id])
                redirect action:"index", method:"GET"
            }
            '*'{ render status: NO_CONTENT }
        }
    }

    protected void notFound() {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'registration.label', default: 'Registration'), params.id])
                redirect action: "index", method: "GET"
            }
            '*'{ render status: NOT_FOUND }
        }
    }
}

这是我的大学项目,所以我需要帮助,而且我无法理解我需要做些什么才能解决这个问题。

2 个答案:

答案 0 :(得分:0)

问题显然来自&#34;创造&#34;动作被触发。从异常消息判断&#34; car&#34;未传递给视图。删除&#34;回复&#34;行动声明。

试试这个:

def create() { 
    [car: Car.get(params.carId)]
}

答案 1 :(得分:0)

您需要将${car.id}作为create控制器中操作registeration的ID。在car / index.gsp中,传递ID也在g:link

<g:link action="create" controller="registration" id="${car.id}" params="${[carId : car.id ]}">

现在您已将值car.id作为carId传递。它将在“保存”操作中可用。现在你必须将这辆车与注册联系起来。在保存操作中执行此操作,而不是在创建操作中执行此操作。

在注册控制器保存操作中:

// After checking no errors //
def selectedCar=Car.get(params.carId)
registeration.rentedcar=selectedcar
registration.save flush:true

创建操作只需要

 respond new Registration(params)

OR而不是汽车/索引中的参数,你可以在registration / create.gsp

中使用它
<input type="hidden" name="carId" id="carId" value="${params.id}"/>