在控制器的方法中不使用 head on list

Not using head on list inside the method of a controller

我有以下控制器方法:

  def edit(bookId: Int): Action[AnyContent] = messagesAction {implicit request => {
    val books = Book.getBookId(bookId)
    if(books.nonEmpty) Ok(views.html.book.create(bookForm.fill(books.head)))
    else NotFound("Book is not found.")
  }}

但我对自己的做法并不满意。

其实我不想测试list(books val)的空性。

我试过类似的东西:

  def edit2(bookId: Int): Action[AnyContent] = messagesAction {implicit request => {
    Book.getBookId(bookId).foreach(book => Ok(views.html.book.create(bookForm.fill(book))))
    NotFound("Book is not found.")
  }}

它确实可以编译,但我每次都有 NOtFound 重定向。

我该怎么做?

你的第二个代码示例不起作用的原因是因为方法的最后一个表达式的结果被用作 return 值,所以在你的情况下它总是 NotFound(...) .

如果您不想在 books.nonEmpty 上进行测试,您可以像

这样使用 headOption
Book.getBookId(bookId).headOption
  .map(book => Ok(views.html.book.create(bookForm.fill(book)))))
  .getOrElse(NotFound("Book is not found."))

但我不确定这是否比您原来的解决方案更容易理解。

也许您只是在寻找模式匹配?

Book.getBookId(bookId) match {
   //get head of list and ignore rest
   case book :: _ => Ok(views.html.book.create(bookForm.fill(book)))
   //if list is empty return not found 
   case Nil       => NotFound("Book is not found.")
}

你也可以这样折叠选项

Book.getBookId(bookId).headOption.fold(NotFound("Book is not found.")) { book =>
  Ok(views.html.book.create(bookForm.fill(book)))
}