liftweb: получение модельного поля - PullRequest
2 голосов
/ 12 августа 2010

Я новичок в лифте и скале. Я разрабатываю json-rest api для rss agregator, и у меня есть две проблемы:

package my.domain

import net.liftweb.http._
import net.liftweb.http.rest._
import net.liftweb.json.JsonAST._
import net.liftweb.common.{Box,Full,Empty,Failure,ParamFailure}


import my.domain.model.{RssItem}

object ContentRest extends RestHelper {
 def getFirstRssItem = {
  val item = RssItem.find(ByField(RssItem.title, "test"))
  item.title
 }
 serve {
     case "api" :: "static" :: _ XmlGet _=> <b>Static</b>
     case "api" :: "static" :: _ JsonGet _ => JString("string")
 }
}

Я получаю ошибки в первой и второй строках метода getFirstRssItem:

Во-первых, компилятор не может найти метод ByField - что мне нужно импортировать?

Во-вторых, компилятор говорит, что не может найти заголовок метода в item val. В соответствии с wiki liftweb я могу назвать имя поля как метод, но item имеет тип Box [my.domain.model.RssItem] Что я делаю неправильно? Модель RssItem:

package my.domain.model

import net.liftweb.mapper._

class RssItem extends KeyedMapper[Long, RssItem] {

    def getSingleton = RssItem

    def primaryKeyField = id
    object id extends MappedLongIndex(this)
    object title extends MappedString(this, 255)
    object description extends MappedText(this)
    object pubDate extends MappedDateTime(this)
}

object RssItem extends RssItem with KeyedMetaMapper[Long, RssItem] {
    def dbTable = "items"
}

Ответы [ 3 ]

1 голос
/ 24 августа 2010

Как указывает Дебилски, find () возвращает Box [RssItem], который пуст, если нет элементов, или Full (элемент), если элемент был найден, поэтому для получения заголовка требуется карта () или использование для понимания. (что является синтаксическим сахаром на карте / flatMap / фильтр).

С точки зрения вашего запроса, вы хотите By (), а не ByField (). Я очистил ваш код, чтобы он компилировался:

object ContentRest extends RestHelper {
  def getFirstRssItemTitle = {
    for {
      item <- RssItem.find(By(RssItem.title, "test"))
    } yield item.title
  }

  serve {
    case "api" :: "static" :: _ XmlGet _=> 
    for {
      title <- getFirstRssItemTitle ?~ "No RSS data"
    } yield <b>{title}</b>
  }
}

Обратите внимание, что если в базе данных нет элементов, вы вернете 404 с "Нет данных RSS" в теле (а не исключение нулевого указателя.)

Надеюсь, это поможет.

0 голосов
/ 13 августа 2010

Find возвращает Box (который вы можете использовать точно так же, как Option), потому что неясно, можно ли найти фактический элемент.

Вместо item.title вы бы написали что-то вроде

item.map(_.title) openOr "untitled"

item.map(_.title) дает вам Box заголовка, который либо содержит заголовок, либо является пустым (если элемент не был найден). Без Box у вас будет нулевая ошибка. openOr затем либо возвращает содержимое Box, либо указанное значение по умолчанию.

0 голосов
/ 12 августа 2010

Интересно, можно ли попробовать использовать net.liftweb.mapper.By (вместо ByField), что-то вроде ...

импорт net.liftweb.mapper.By

val item = RssItem.find (By (RssItem.title, "test")

...