Как изменить логическое значение false в домене на логическое значение true в контроллере

#variables #grails #groovy #boolean

#переменные #grails #groovy #логическое

Вопрос:

У меня есть класс домена с логической переменной «false». Теперь я хочу изменить это логическое значение в моем контроллере в методе на «true», как я могу решить эту проблему?

Спасибо!

Домен:

 class Test {
 
  Boolean status = false

  static constraints = {
   
  }
}
 

Метод контроллера:

 def setTestDone(){
        def setTestDone = Test.get(params.id)
        try{
            setTestDone.status = true
        } catch (RuntimeException runtimeException) {
            flash.error = runtimeException.message
        }
        redirect(controller:"test", action: "index")
    }
 

Комментарии:

1. Пожалуйста, добавьте код, который вы пробовали, и как он не удался (например, ошибки, трассировки стека, журналы, …), Чтобы мы могли его улучшить.

2. Я добавил это выше

3. Как проявляется сбой? Это тот случай, когда поток выполнения соответствует ожиданиям, но изменение статуса не фиксируется в базе данных?

4. Поток выполнения соответствует ожиданиям, но логический статус остается false и не изменился на true

Ответ №1:

Смотрите проект на https://github.com/jeffbrown/mrcreatesavestatus .

https://github.com/jeffbrown/mrcreatesavestatus/blob/95ac4b7f2826b94746bc8825fc94dbaa6812ee66/grails-app/domain/mrcreatesavestatus/Test.groovy

 package mrcreatesavestatus

class Test {
    Boolean status
}
 

https://github.com/jeffbrown/mrcreatesavestatus/blob/95ac4b7f2826b94746bc8825fc94dbaa6812ee66/grails-app/services/mrcreatesavestatus/TestService.groovy

 package mrcreatesavestatus

import grails.gorm.services.Service

@Service(Test)
interface TestService {
    Test get(Serializable id)

    Test save(Boolean status)

    Test update(Serializable id, Boolean status)
}
 

https://github.com/jeffbrown/mrcreatesavestatus/blob/95ac4b7f2826b94746bc8825fc94dbaa6812ee66/grails-app/controllers/mrcreatesavestatus/TestController.groovy

 package mrcreatesavestatus

class TestController {

    TestService testService

    def updateStatusTrue(Long id) {
        respond testService.update(id, true)
    }

    def updateStatusFalse(Long id) {
        respond testService.update(id, false)
    }

    def show(Long id) {
        respond testService.get(id)
    }
}
 

https://github.com/jeffbrown/mrcreatesavestatus/blob/95ac4b7f2826b94746bc8825fc94dbaa6812ee66/grails-app/init/mrcreatesavestatus/BootStrap.groovy

 package mrcreatesavestatus

class BootStrap {

    TestService testService
    def init = { servletContext ->
        // save a Test instance with
        // status set to false
        testService.save false
    }
    def destroy = {
    }
}
 

Эти обновления работают хорошо:

  $ http :8080/test/show/1.json
HTTP/1.1 200 
Connection: keep-alive
Content-Type: application/json;charset=UTF-8
Date: Fri, 11 Dec 2020 13:22:50 GMT
Keep-Alive: timeout=60
Transfer-Encoding: chunked

{
    "id": 1,
    "status": false
}

 $ http :8080/test/updateStatusTrue/1.json
HTTP/1.1 200 
Connection: keep-alive
Content-Type: application/json;charset=UTF-8
Date: Fri, 11 Dec 2020 13:23:02 GMT
Keep-Alive: timeout=60
Transfer-Encoding: chunked

{
    "id": 1,
    "status": true
}

 $ http :8080/test/updateStatusFalse/1.json
HTTP/1.1 200 
Connection: keep-alive
Content-Type: application/json;charset=UTF-8
Date: Fri, 11 Dec 2020 13:23:09 GMT
Keep-Alive: timeout=60
Transfer-Encoding: chunked

{
    "id": 1,
    "status": false
}
 

Ответ №2:

Если вы используете grails, попробуйте следующее

Домен

 class Test {
 
  boolean status // by default is false

  static constraints = {
   
  }
}
 

Контроллер

 def setTestDone(){
   def setTestDone = Test.get(params.id)
   setTestDone.status = true
   setTestDone.save(flush:true)
   redirect(controller:"test", action: "index")
}
 

Флаг flush немедленно вызовет транзакцию, но сначала я предлагаю создать сервис, который выполняет такую работу, уровень сервиса по умолчанию является транзакционным, поэтому у вас может быть что-то вроде этого:

Обслуживание

 @Transactional
class TestService {
     Test save(id){
        Test test = Test.get(id)
        test.status = true
        test.save(flush:true)
     }
}
 

И ваш контроллер должен выглядеть так:

Контроллер

 class TestController {

  def testService // injected by convention

  def updateTest() {
     testService.save(params.id)
     redirect(controller:"test", action: "index")
  }
}
 

Надеюсь, это сработает для вас.

Комментарии:

1. Если я попробую это, я получу ecxeption: Class: java.lang. Сообщение об исключении NullPointerException: null вызвано: невозможно вызвать метод save() для нулевого объекта

Ответ №3:

Вам необходимо вызвать save() метод для сохранения изменений в БД:

  def setTestDone = Test.get params.id
 setTestDone.status = true
 if( !setTestDone.save() )
   println setTestDone.errors
 

Дополнительную информацию о дополнительных параметрах см. в ref-doc.

Комментарии:

1. Я добавил метод save(), но ничего не изменилось, также, если я добавлю setTestDone.save(flush: true), ничего не произошло

2. обычно это означает, что ваш объект не проходит проверку. см. Обновление