WIth Squeryl (using Lift), how can I make two model classes a subclass of the same class? - lift

Using Lift with Squeryl, how can I make two classes a subclass of the same class?
My classes look like the following:
class SubClass1 extends Record[SubClass1] with KeyedRecord[SubClass1] with CreatedUpdated[SubClass1] {
val id = ...
val field1a = StringField(...)
...
}
class SubClass2 extends Record[SubClass2] with KeyedRecord[SubClass2] with CreatedUpdated[SubClass2] {
val id = ...
val field2a = StringField(...)
}
I want SubClass1 and SubClass2 each to be a child class of some other class, say MyParentClass. So I would think that I would have to do something like this:
abstract class MyParentClass extends Record[MyParentClass] with KeyedRecord[MyParentClass] with CreatedUpdated[MyParentClass] {}
and then
class SubClass1 extends MyParentClass {
val id = ...
val field1a = StringField(...)
...
}
class SubClass2 extends MyParentClass {
val id = ...
val field2a = StringField(...)
...
}
This gives me errors, such as the fields (StringField) etc. not conforming to the right type. Any suggestions on how to do this?
Thanks,

You abstract superclass can't define a concrete type parameter, since it needs to be overriden by the subclasses. Try:
abstract class MyParentClass[A <: MyParentClass]
extends Record[A] with KeyedRecord[A] with CreatedUpdated[A]
Then:
class SubClass extends MyParentClass[SubClass]

Related

Pass constant to super constructor

How can I pass a constant from a sub class to a super constructor? Something like:
class SubClass extends SuperClass(Const) {
val Const = ...
}
Constants are usually placed in companion objects, so you can do it as follows:
class SubClass extends SuperClass(SubClass.Const)
object SubClass {
val Const = ...
}

Scala subtype parameter

I created a class Project extending a Model:
abstract class Model
case class Project(...) extends Model
and an object Table extending Base:
abstract class Base {
val tableForm: Form[Model]
}
object Table extends Base {
val tableForm: Form[Project] = (...)
}
Why is it that it won't compile and how can I fix it? ("overriding method/value tableForm in class Base of type => Form[Model]")
I just wanted to force all subclasses of Base to have a tableForm attribute.
Because Form[Project] is not a subclass of Form[Model]. So the compiler complains about incompatible type in overriding value.
Form[T] is invariant. You can read the variance doc
To fix this, you can add a type parameter to Base.
abstract class Base[M <: Model] {
val tableForm: Test[M]
}
object Table extends Base[Project] {
val tableForm: Test[Project] = ???
}

Google Guice field injection in scala case class

I am writing Play 2.5 application using Scala. I have following piece of code:
#ImplementedBy(classOf[BarRepositoryImpl])
trait BarRepository {
def bar = //some actions
}
class BarRepositoryImpl extends BarRepository
case class Foo( /*some fields*/) {
#Inject private var barRepository: BarRepository = null
def foo1 = {
val a = barRepository.bar //here barRepository is always null
// some actions with 'a' and returning some result which depends on 'a'
}
}
I also have a controller where I inject BarRepository as well, but through constructor and there everything works well while in the class Foo on the line val a = barRepository.bar I get a NullPointerException. Could someone help to figure out what's the problem? Is it forbidden to use injection in case class?
If you don't want to pollute your case class signature with Guice injected annotation and fields then simply add an implicit dependency on the method that needs it instead:
case class Foo( /*some fields*/) {
def bar1(someField: Int)(implicit barRepository: BarRepository) = {
// some code that interacts with barRepository
}
}
The calling class will have to have the BarRepository as an implicitly injected parameter. E.g. a Play controller like:
#Singleton
class HomeController #Inject()(cc: ControllerComponents)
(implicit barRepository: BarRepository)
extends AbstractController(cc) {
def index() = Action { implicit request =>
val foo = Foo("field")
val bar = foo.bar1
// ...
}
}
I would have assumed that you inject the object in your class signature?
case class Foo #Inject()(barRepository:BarRepository, /* your fields */){
/** some stuff **/
}

Scala traits exposing protected members?

Given a class like:
class MyClass {
protected object MyObj { ... }
}
is it possible to write a trait that will permit exposing MyObj. E.g. with inheritance I could do the following:
class TestMyClass extends MyClass {
val getMyObj = MyObj
}
but I want to do this via a trait, something like the following which doesn't typecheck:
trait ExposeMyObj {
val getMyObj = MyObj // super.MyObj/this.MyObj don't work
}
and use it like:
class TestMyClass extends ExposeMyObj
Is it possible to reproduce the functionality in TestMyClass into a trait to expose the protected object, and if so how?
If you know that your trait will always be mixed in to an instance of MyClass (or a subclass), you can enforce the expectation with a self-type, and then access the object:
trait ExposeMyObj {
self: MyClass =>
val getMyObj = MyObj
}
Edit: an example of using this trait:
class TestMyClass extends MyClass with ExposeMyObj
val test = new TestMyClass
test.getMyObj // accesses MyObj defined in MyClass.
Edit 2: attempting to address #jbrown's comment (re: testing queries within repos) - I would look at doing something like the following - first, in each repo's file, add a trait for each repo holding the queries for that repo:
trait UserQueries { // you could look at making this protected, if you like
protected def query1(param: String) = List(param) // very silly implementation, but hopefully enough to make the point
... // other queries
}
class UserRepo extends UserQueries // Has (internal) access to those queries
Then in the test class file for a given repo:
class UserQueriesTester extends UserQueries with ScalaTest { // or whatever test framework you are using
// (public) tests to run - eg:
def testQuery1 = query1("test") should be (List("test"))
}

Scala abstract class method that returns a new corresponding class child object

I have the following class in my mind:
abstract class MyClass (data: MyData) {
def update(): MyClass = {
new MyClass(process())
}
def process(): MyData = {
...
}
}
However, abstract classes cannot be instantiated so the line new MyClass(process()) is an error. My question is - is there any way to tell the compiler that in case of each of the child classes of MyClass I want to create an object of exactly that child class? It seems an overkill to write this method awhole in all child classes. Playing with type parameters of the class or method I could not acheive that myself.
How about something like this? MyClass is parametrized with the concrete type. Of course, all concrete classes have to implement a method that actually returns a new instance of Self.
trait MyClass[+Self <: MyClass[Self]] {
def update(): Self = {
makeNew(process())
}
def process(): MyData = {
// ...
}
protected def makeNew(data: MyData): Self
}
class Concrete0 extends MyClass[Concrete0] {
protected def makeNew(data: MyData) = new Concrete0
}
class RefinedConcrete0 extends Concrete0 with MyClass[RefinedConcrete0] {
override protected def makeNew(data: MyData) = new RefinedConcrete0
}
Credit: IttayD’s second update to his answer to this question.
To completly avoid implementing almost identical method in all subclasses you would need to use reflection. I guess that would be your last resort if you have chosen Scala.
So here is how to minimize the repetitive code:
// additional parameter: a factory function
abstract class MyClass(data: MyData, makeNew: MyData => MyClass) {
def update(): MyClass = {
makeNew(process())
}
def process(): MyData = {
...
}
}
class Concrete(data: MyData) extends MyClass(data, new Concrete(_))
This way you repeat only the shortest fragment required to instantiate the subclass.