Liftことはじめ その5 mapper OneToMany
前述の記事の覚書
LiftのORMでOneToManyを実装。
各trackの添付を複数指定可能にする。(必然性はないが、音楽ファイルとTab符とか)
One側のTrackクラスは、OneToManyをMixIn。属性にattachesを定義。
model/Track
package code.model
import net.liftweb.mapper._
import net.liftweb.util._
import net.liftweb.common._
object Track extends Track with LongKeyedMetaMapper[Track] {
override def dbTableName = "tracks"
}
class Track extends LongKeyedMapper[Track] with IdPK with OneToMany[Long, Track]{
def this(albumid: Long, seq: Long, tracktitle: String) = {
this()
this.albumid(albumid)
this.seq(seq)
this.tracktitle(tracktitle)
}
def getSingleton = Track
object albumid extends MappedLong(this)
object seq extends MappedLong(this)
object tracktitle extends MappedString(this, 100) {
override def validations =
valMaxLen(100, "name length must be under 100 characters long ") _ ::
valMinLen(1, "you have to input!!") _ ::
super.validations
}
object attaches extends MappedOneToMany(Attach, Attach.track, OrderBy(Attach.id, Ascending))
}Many側のAttachクラス。属性にtrackを定義。
package code.model
import net.liftweb.mapper._
object Attach extends Attach with LongKeyedMetaMapper[Attach] {
override def dbTableName = "attaches"
}
class Attach extends LongKeyedMapper[Attach] with IdPK {
def getSingleton = Attach
def this(filename: String, mimetype: String, trackattach: Array[Byte]) = {
this()
this.filename(filename)
this.mimetype(mimetype)
this.trackattach(trackattach)
}
object filename extends MappedString(this, 100)
object mimetype extends MappedString(this, 40)
object trackattach extends MappedBinary(this)
object track extends LongMappedMapper(this, Track)
}利用は、以下のようなコード。
package code.snippet
import java.io._
import scala.xml.{NodeSeq, Text}
import net.liftweb.util._
import net.liftweb.common._
import Helpers._
import code.model._
import net.liftweb.mapper._
import net.liftweb.http._
import S._
import SHtml._
import net.liftweb.http.js.{JsCmd, JsCmds}
class TrackView {
…
// Save
def addProcess() {
try {
val track: Track = isAtachFileExist(upload) match {
case true => {
val attach: Attach = new Attach(getFileParamHolder(upload).fileName, getFileParamHolder(upload).mimeType, getFileParamHolder(upload).file)
val track: Track = Track.create.albumid(albumid.toLong).seq(seq.toLong).tracktitle(tracktitle)
track.attaches += attach
track.save
track
}
case false => new Track(albumid.toLong, seq.toLong, tracktitle)
}
track.validate match{
case Nil => {
track.save()
S.notice("Added " + track.tracktitle)
S.redirectTo("/track?albumid=" + albumid)
}
case x => {
S.error("Validation Error!")
S.redirectTo("/track?albumid=" + albumid)
}
}
} catch {
case e: java.lang.NumberFormatException => {
S.error("SEQ must be the number!")
S.redirectTo("/track?albumid=" + albumid)
}
}
}
// Select
private def doList(reDraw: () => JsCmd)(html: NodeSeq): NodeSeq = {
val tracks:List[Track] = Track.findAll(By(Track.albumid, getAlbumId().toLong), OrderBy(Track.seq, Ascending))
bind("track", html, "albumid" -> <input type="text" name="albumid" class="column span-10"/>)
tracks.flatMap(trk => {
trk.attaches.flatMap(atc => {
…
}