Slick

2013-03-02 9 views
5

में सहयोगी ऑब्जेक्ट के साथ एक केस क्लास के साथ मैप किए गए प्रोजेक्शन को स्लिक के साथ, मैं डेटाबेस तालिका प्रविष्टियों को सीधे उस केस क्लास में प्रोजेक्ट करने की कोशिश कर रहा हूं जो वे प्रतिनिधित्व करते हैं। example in the documentation के बाद, मैं एक मैप किए गए प्रक्षेपण <> ऑपरेटर का उपयोग करके सेट:Slick

case class SomeEntity3(id: Int, entity1: Int, entity2: Int) 

val SomeEntityTable = new Table[SomeEntity3]("some_entity_table") { 
    def id = column[Int]("id", O.PrimaryKey, O.AutoInc) 
    def entity1 = column[Int]("entity1") 
    def entity2 = column[Int]("entity2") 

    def * = id ~ entity1 ~ entity2 <> (SomeEntity3, SomeEntity3.unapply _) 
} 

अब, मैं SomeEntity3 करने के लिए कुछ स्थिर स्थिरांक और सहायक तरीकों जोड़ना चाहते हैं। इसके लिए, मैं एक साथी वस्तु बनाते हैं। लेकिन जैसे ही मैंने लाइन

object SomeEntity3 

एक सुंदर जंगली बहु लाइन त्रुटि * की परिभाषा कुछ के बारे में "अतिभारित विधि मूल्य <> विकल्प के साथ" अस्पष्ट कह के लिए पॉप अप होता है शामिल हैं।

साथी ऑब्जेक्ट स्लिम में द्वि-दिशात्मक मैपिंग से कैसे संबंधित है और क्या मैं अपना लक्ष्य पूरा कर सकता हूं?

उत्तर

8

साथी वस्तुओं आमतौर पर ऐसा वर्ग 'मामले वर्ग के लिए पहला तर्क सूची में से एक समारोह कर रहे हैं। तो अगर आप था

case class Fnord(a: A, b: B, c: C)(d: D) 

स्काला संकलक साथी autogenerate हैं

object Fnord extends ((A, B, C) => Fnord) { 
    ... 
} 

के समान वस्तु अब, जैसे ही आप स्पष्ट रूप से साथी ऑब्जेक्ट को स्वयं के बारे में कुछ उल्लेख, संकलक नहीं रह गया है उत्पन्न करता है FunctionN चीज विस्तारित। इस प्रकार, ज्यादातर समय इसे स्वयं जोड़ना एक अच्छा विचार है। आपके मामले में कि इतने तरह SomeEntity3 का साथी को परिभाषित करने का मतलब होगा: https://issues.scala-lang.org/browse/SI-3664

9

ठीक काफी सरल है: मामले वर्गों के

def * = id ~ entity1 ~ entity2 <> (SomeEntity3.apply _, SomeEntity3.unapply _) 
+0

यह काम करता है वास्तव में:

class WidgetTable(tag: Tag) extends Table[WidgetEntity](tag, "widget_tbl") { def id = column[Int]("id",O.PrimaryKey) def foo = column[String]("foo") override def * = (id,foo) <> ((WidgetEntity.apply _).tupled,WidgetEntity.unapply) } 

पूर्ण विवरण देखें। स्पेलिंग क्यों स्पष्ट रूप से लागू होती है इस पर कोई स्पष्टीकरण की आवश्यकता है और समस्या को हल करता है? – notan3xit

+1

स्पष्ट रूप से लागू विधि को एक फ़ंक्शन (ईटा विस्तार) में बदलना '(Int, Int, Int) => SomeEntity3' उत्पन्न करता है, यानी वह प्रकार जो साथी ऑब्जेक्ट को पहले स्थान पर होना चाहिए। अधिक आम तौर पर, एक फ़ंक्शन ऑब्जेक्ट को "नई" फ़ंक्शन ऑब्जेक्ट में लागू विधि को मूल कार्य के समान प्रकार उत्पन्न करता है। –

+0

किसी कारण से स्केलैक भ्रमित हो जाता है जब आपके पास कोई साथी ऑब्जेक्ट होता है और ऑब्जेक्ट के आवेदन को लिफ्ट नहीं करता है। – pedrofurla

1

यह वस्तुओं चालू करने के लिए है करने के लिए एक और तरीका है:

object SomeEntity3 extends ((Int, Int, Int) => SomeEntity3) { 
    ... 
} 

एक (लंबी खुली) इस व्यवहार के लिए भी मुद्दा नहीं है विधि को एक टुपल में लागू करें और <> को नीचे दिखाए गए अनुसार पास करें।

package models 

import play.api._ 
import play.api.libs.json._ 
import scala.slick.driver.H2Driver.simple._ 

case class User(
    name: String, 
    id: Option[Int] = None 
) 

object User { 
    implicit val format = Json.format[User] 
} 

class UserTable(tag: Tag) extends Table[User](tag, "USERS") { 
    def id = column[Int]("ID", O.PrimaryKey, O.AutoInc) 
    def name = column[String]("NAME", O.NotNull) 

    def * = (name, id.?) <> ((User.apply _).tupled, User.unapply) 
} 

object Users extends TableQuery(new UserTable(_)) { 
    val findByID = this.findBy(_.id) 
} 
0

व्यक्तिगत रूप से, मामले वर्ग से आंशिक रूप से लागू किया apply विधि मेरी सेटअप और स्लिक 3.0 के साथ काम नहीं करता।

हालांकि यह काम करता है, उचित tupled विधि परोक्ष रूप से करने के लिए बिल खोदने:, https://stackoverflow.com/a/38589579/564157

संबंधित मुद्दे