Reputation: 65
When I enter data into the form fields and click on "Add book" button it happens nothing... The entered data into fields it's not added into the database, I receive no error and I don't know what I'm doing wrong...
I have the following controller
package controllers
import play.api.data.Form
import play.api.data.Forms._
import play.api.mvc.{Action, Controller}
import anorm.NotAssigned
import play.api.Play.current
import play.api.i18n.Messages.Implicits._
import models.Buch
object Book extends Controller{
val addBookForm = Form(
mapping(
"name" -> nonEmptyText,
"author" -> nonEmptyText,
"category" -> nonEmptyText,
"read" -> boolean,
"amount" -> number
)(Buch.apply)(Buch.unapply)
)
def add = Action {
Ok(views.html.book(addBookForm))
}
def addBuch() = Action { implicit request =>
addBookForm.bindFromRequest.fold(
errors => BadRequest,
{
case Buch(name, author, category, read, amount) =>
Buch.addBook(Buch(name, author, category, read, amount))
Ok("Book successfully added!")
}
)
}
}
The following model
package models
import play.api.db._
import play.api.Play.current
import anorm._
import anorm.SqlParser._
case class Buch(name:String, author:String, category:String, read:Boolean, amount: Int)
object Buch{
val simple = {
get[String]("buch.name") ~
get[String]("buch.auhtor") ~
get[String]("buch.category") ~
get[Boolean]("buch.read") ~
get[Int]("buch.amount") map {
case name~author~category~read~amount => Buch(name, author, category, read, amount)
}
}
def findAll(): Seq[Buch] = {
DB.withConnection { implicit connection =>
SQL("select * from buch").as(Buch.simple *)
}
}
def addBook(buch:Buch): Unit = {
DB.withConnection { implicit connection =>
SQL("insert into buch(name, author, category, read, amount) values ({name}, {author}, {category}, {read}, {amount})").on(
'name -> buch.name,
'author -> buch.author,
'category -> buch.category,
'read -> buch.read,
'amount -> buch.amount
).executeUpdate()
}
}
}
The following sql script
# Buch schema
# --- !Ups
CREATE TABLE Buch (
id bigint(20) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
author varchar(255) NOT NULL,
category varchar(255) NOT NULL,
read boolean NOT NULL DEFAULT '0',
amount int(11) NOT NULL,
PRIMARY KEY (id)
);
# --- !Downs
DROP TABLE Buch;
The following view
@(form: Form[Buch])(implicit messages: Messages)
@main("Welcome to Play 2.0") {
@helper.form(action = routes.Book.addBuch) {
@helper.inputText(form("name"))
@helper.inputText(form("author"))
@helper.inputText(form("category"))
@helper.inputText(form("read"))
@helper.inputText(form("amount"))
<input type="submit" value="Add book"/>
}
}
If I modify the model, for example creating it with only 3 parameters, name, author and category the method addBook will insert the data into my database.
Can anyone please tell what am I doing wrong?
Thank you!
Upvotes: 2
Views: 656
Reputation: 8851
In mysql, read
is a reserved word. See docs.
CREATE TABLE Buch (
id bigint(20) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
author varchar(255) NOT NULL,
category varchar(255) NOT NULL,
read boolean NOT NULL DEFAULT '0',
amount int(11) NOT NULL,
PRIMARY KEY (id)
);
You should replace it with some non-reserved word (e.g. book_read) or escape it by putting in backticks like this:
CREATE TABLE Buch (
id bigint(20) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
author varchar(255) NOT NULL,
category varchar(255) NOT NULL,
`read` boolean NOT NULL DEFAULT '0',
amount int(11) NOT NULL,
PRIMARY KEY (id)
);
Edit:
Anorm does not provide default mapping from mysql boolean to scala boolean. From its documentation:
It’s possible to add custom mapping, for example if underlying DB doesn’t support boolean datatype and returns integer instead. To do so, you have to provide a new implicit conversion for Column[T], where T is the target Scala type:
import anorm.Column // Custom conversion from JDBC column to Boolean implicit def columnToBoolean: Column[Boolean] = Column.nonNull1 { (value, meta) => val MetaDataItem(qualified, nullable, clazz) = meta value match { case bool: Boolean => Right(bool) // Provided-default case case bit: Int => Right(bit == 1) // Custom conversion case _ => Left(TypeDoesNotMatch(s"Cannot convert $value: ${value.asInstanceOf[AnyRef].getClass} to Boolean for column $qualified")) } }
Also see this discussion on Anorm - Mysql Boolean.
Upvotes: 1