1

私のプロジェクトでは、ツリー モデルを作成したいと思います。ファイルとディレクトリに関するものだとしましょう。ただし、ファイルは同時に複数のディレクトリにある可能性があるため、gmail でメールにタグを追加するのと同じ方法に似ています。コンピテンス (java、scala、angular など) のモデルを構築し、それらをカテゴリに分類したいと考えています。この場合、java と scala は言語、agila と scrum は作業方法、angular はフレームワーク/ツールキットなどです。ただし、柔軟にグループ化する必要があります。つまり、play、java、scala は「バックエンド」カテゴリにあり、angular、jquery などはフロントエンド カテゴリにあります。

私は次のようなテーブル能力を持っていると考えました:

case class Competence (name: String, categories: Option[Category])

カテゴリは次のとおりです。

case class Category ( name: String, parent: Option[Category] )

これはコンパイルされますが、SORM は (アクティベーター コンソールから) エラーを生成します。

scala> import models.DB
import models.DB
scala> import models.Category
import models.Category
scala> import models.Competence
import models.Competence
scala> val cat1 = new Category ( "A", None )
cat1: models.Category = Category(A,None)
scala> val sav1 = DB.save ( cat1 )
sorm.Instance$ValidationException: Entity 'models.Category' recurses at 'models.Category'
  at sorm.Instance$Initialization$$anonfun$2.apply(Instance.scala:216)
  at sorm.Instance$Initialization$$anonfun$2.apply(Instance.scala:216)
  at scala.Option.map(Option.scala:146)
  at sorm.Instance$Initialization.<init>(Instance.scala:216)
  at sorm.Instance.<init>(Instance.scala:38)
  at models.DB$.<init>(DB.scala:5)
  at models.DB$.<clinit>(DB.scala)
  ... 42 elided

sorm の美しいシンプルさが欲しいのですが、プロジェクトでこれを実装するには Slick に切り替える必要がありますか? 私は、リンク テーブルが sorm によって暗黙的に生成されるという考えを持っていました。または、次のようにして問題を回避できますか。

case class Taxonomy ( child: Category, parent: Category )

JS側で解析/フォーマット作業を行いますか? sorm を使用することの単純さがいくらか失われているようです。

アイデアを与えるために、ユーザーが左側のリストに新しい能力を追加できる ajaxy ページを作成し、それらをツリー内の好きなカテゴリ タグにリンク/リンク解除することを望んでいます。

4

1 に答える 1

1

同じ質問に遭遇しました。連鎖(再帰)できる2つのオペラント間の相互作用を定義する必要がありました。お気に入り:

case class InteractionModel(
    val leftOperantId: Int,
    val operation: String ,
    val rightOperantId: Int,
    val next: InteractionModel)

私の回避策:このケースクラスを Json(String) に変更し、それを取得するときに Json から変換して String として永続化します。また、文字列なのでsorm Entityとして登録しないでください。

import spray.json._
case class InteractionModel(
    val leftOperantId: Int,
    val operation: String ,
    val rightOperantId: Int,
    val next: InteractionModel) extends Jsonable {
  def toJSON: String = {
    val js = this.toJson(InteractionModel.MyJsonProtocol.ImJsonFormat)
    js.compactPrint
  }
}

//define protocol
object InteractionModel {
  def fromJSON(in: String): InteractionModel = {
    in.parseJson.convertTo[InteractionModel](InteractionModel.MyJsonProtocol.ImJsonFormat)
  }

  val none = new InteractionModel((-1), "", (-1), null) {
    override def toJSON = "{}"
  }

  object MyJsonProtocol extends DefaultJsonProtocol {
    implicit object ImJsonFormat extends RootJsonFormat[InteractionModel] {
      def write(im: InteractionModel) = {
        def recWrite(i: InteractionModel): JsObject = {
          val next = i.next match {
            case null  => JsNull
            case iNext => recWrite(i.next)
          }
          JsObject(
            "leftOperantId" -> JsNumber(i.leftOperantId),
            "operation" -> JsString(i.operation.toString),
            "rightOperantId" -> JsNumber(i.rightOperantId),
            "next" -> next)
        }
        recWrite(im)
      }
      def read(value: JsValue) = {
        def recRead(v: JsValue): InteractionModel = {
          v.asJsObject.getFields("leftOperantId", "operation", "rightOperantId", "next") match {
            case Seq(JsNumber(left), JsString(operation), JsNumber(right), nextJs) =>
              val next = nextJs match {
                case JsNull => null
                case js     => recRead(js)
              }
              InteractionModel(left.toInt, operation, right.toInt, next)
            case s => InteractionModel.none
          }
        }
        recRead(value)
      }
    }
  }
}
于 2016-07-14T08:36:45.287 に答える