I am new with liftweb and scala. I am developing json-rest api for rss agregator and I have two problems:
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")
}
}
I get errors on both first and second lines of getFirstRssItem method:
First is that compiler can't find ByField method - what i need to import?
Second is that compiler says it can't find method title in item
val. According to liftweb wiki I may ca开发者_开发百科ll field's name as method but item
has the type Box[my.domain.model.RssItem]. What am I doing wrong?
RssItem model:
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"
}
As Debilski points out, find() return a Box[RssItem] which is Empty if there are no items or Full(item) if an item was found, so getting the title requires a map() or using the for comprehension (which is syntactic sugar on map/flatMap/filter).
In terms of your query, you want By() rather than ByField(). I've cleaned up your code so it compiles:
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>
}
}
Note that if there are no items in the database, then you'll return a 404 with "No RSS data" in the body (rather than a null pointer exception.)
I hope this helps.
Wondering whether you can try using net.liftweb.mapper.By (instead of ByField), something like ...
import net.liftweb.mapper.By
val item = RssItem.find(By(RssItem.title, "test")
Find
returns a Box
, (which you can use just like Option
,) because it is not clear whether an actual element can be found.
Instead of item.title
, you would write something like
item.map(_.title) openOr "untitled"
item.map(_.title)
gives you a Box
of the title which either contains the title or is empty (in case no item was found). Without a Box
, you’d have a Null error there. openOr
then either returns the contents of the Box
or specified default value.
精彩评论