Я сейчас читаю Scala-версию учебника по игре на yabe. yabe означает еще один движок блога, и, естественно, в какой-то момент в учебнике данные должны быть сохранены. Первая эволюция sql это:
# Users schema
# ---!Ups
CREATE TABLE User(
id bigint(20) NOT NULL AUTO_INCREMENT,
email varchar(255) NOT NULL,
password varchar(255) NOT NULL,
fullname varchar(255) NOT NULL,
isAdmin boolean NOT NULL,
PRIMARY KEY (id)
);
# --- !Downs
DROP TABLE User;
После этого добавляются таблицы для постов и комментариев. На стороне scala каждая запись базы данных может быть сопоставлена с классом дел. Его сопутствующий объект расширяет черту Magic и реализует различные вспомогательные функции. Проблема вызвана этим кодом из сопутствующего объекта класса Post. Вам нужно только взглянуть на SQL-запрос:
def allWithAuthor:List[(Post,User)] =
SQL(
"""
select * from Post p
join User u on p.author_id = u.id
order by p.postedAt desc
"""
).as( Post ~< User ^^ flatten * )
Я признаю, что хотя я понимаю, что делает код, я бы никогда не смог придумать это самостоятельно.
Для проверки кода выполняются следующие тесты:
* * 1010
Этот тест заканчивается просто отлично.
Синтаксис Scala добавляет некоторую сложность, но вы можете ясно видеть, что тестовые запросы для пользователя с идентификатором равен 1.
Проблема обнаруживается в этом тесте:
it should "retrieve Posts with author" in {
User.create(User(Id(1), "bob@gmail.com", "secret", "Bob", false))
Post.create(Post(NotAssigned, "My 1st post", "Hello world", new Date, 1))
val posts = Post.allWithAuthor
posts.length should be (1)
val (post,author) = posts.head
post.title should be ("My 1st post")
author.fullname should be ("Bob")
}
Тест не пройден с сообщением об ошибке:
ColumnNotFound (User.id) В /test/Tests.scala, строка 41: val posts =
Post.allWithAuthor
Как идентификатор столбца может исчезнуть таким образом? Я ничего не изменил в коде sql или scala. Простая замена тестов «выключает» ошибку при выключении. Как-то этот sql код
select * from Post p
join User u on p.author_id = u.id
order by p.postedAt desc
не находит идентификатор, пока этот код scala / sql
val users= User.find("id={id}").on("id"->1).as(User*)
делает.
Можете ли вы объяснить, что пошло не так?
Вот ссылка на учебник http://scala.playframework.org/documentation/scala-0.9.1/guide1
UPDATE:
Я прочитал этот вопрос:
СтолбецНе найдена проблема с магией в игре scala
и после комментария отредактировал запрос. Сам sql не изменился, но я вставил все это в одну строку:
def allWithAuthor:List[(Post,User)] =
SQL(
"""select * from Post p join User u on p.author_id = u.id order by p.postedAt desc"""
).as( Post ~< User ^^ flatten * )
Это чудо: теперь колонна найдена. Если запрос длиннее одной строки, тест выдаёт сообщение о странном ColumnNotFoundError, но с помощью oneliner все в порядке.
Как такое может случиться?