I'm currently trying to figure out how to map objects with inheritance
using the Mapper framework. I've got a Lab and a Scientist who inherit
from Source.
As I understand there's no direct way to do inheritance using the
Mapper framework so I'm trying to figure out how to implement 'Single
Table Inheritance'.
Right now I'm trying to create a single trait (Source) for the values
that they share called BaseSource and my idea is to mix it in both Lab
and Scientist. I would then define the table name of both scientist
and lab to be the same - I think this would work but what I'm not sure
of is the following:
- If both Scientist and Lab mixes in the IdPK trait and use the same
table, will the id still be unique?
- A Discovery has a source, how do i create MappedLongForeignKey to
the table they share (lab, scientist)?
I hope you'll be able to help me out :)
Thanks,
Mads Hartmann Jensen
I can't say I follow the above :-) Do you want to share tables, code or
both? Maybe list the table structure and explain how you would like to
map it....
/Jeppe
In my project I've got the following three models: A discovery, a
Scientist and a lab. The Discovery has been invented by someone, this
is either a single scientist or sometimes a lab - This is easily done
through inheritance (would create a superclass named source) but I'm
not sure how to do this so it maps nicely to the database.
Scientist and Lab only share one attribute so what I'm most interested
in is to be able express that a Discovery has s source that can be
either a lab or scientist :)
Hope this explains my problem more clearly, thanks for the help
Mads Hartmann
Sent from my iPhone
> --
> You received this message because you are subscribed to the Google
> Groups "Lift" group.
> To post to this group, send email to lif...@googlegroups.com.
> To unsubscribe from this group, send email to liftweb+u...@googlegroups.com
> .
> For more options, visit this group at http://groups.google.com/group/liftweb?hl=en
> .
>
/------------------------------- code
trait BaseSourceTrait[ T <:BaseSourceTrait[T] ] extends
LongKeyedMapper[T] {
self: T =>
override def primaryKeyField = id
object id extends MappedLongIndex(this)
object name extends MappedPoliteString(this, 256)
object sourceType extends MappedEnum(this,SourceTypes)
object SourceTypes extends Enumeration {
val Scientist = Value("Scientist")
val Lab = Value("Lab")
}
}
class Scientist extends BaseSourceTrait[Scientist] {
def getSingleton = Scientist
object birth extends MappedInt(this)
object death extends MappedInt(this)
object nationality extends MappedPoliteString(this, 128)
}
object Scientist extends Scientist with LongKeyedMetaMapper[Scientist]
{
override def dbTableName = "Source"
}
class Lab extends BaseSourceTrait[Lab] {
def getSingleton = Lab
object institution extends MappedLongForeignKey(this, Institution)
}
object Lab extends Lab with LongKeyedMetaMapper[Lab] {
override def dbTableName = "Source"
}
/------------------------------- code ends
My only problem now is that I can't figure out how to implement the
following:
A Discovery (a mapped class) needs to have a foreign key to the source
that made the discovery, this could be either a lab or a scientist, so
normally i would have a field with a reference to the super-class of
both Scientist and Lab - However, I don't have a super-class, I just
have a trait :)
I would like to be able to write something like this:
/------------------------------- code starts again
class Discovery extends LongKeyedMapper[Discovery] with IdPK {
def getSingleton = Discovery
// primatives
object description extends MappedDateTime(this)
object year extends MappedInt(this)
object reference extends MappedPoliteString(this, 128)
// relationships
object source extends MappedLongForeignKey(this, BaseSourceTrait) //
<-- this is what i want.
}
object Discovery extends Discovery with LongKeyedMetaMapper[Discovery]
/------------------------------- code ends
As always I truely appreciate the help you guys are giving me :)
Thanks,
Mads Hartmann Jensen
On Feb 4, 9:56 pm, David Pollak <feeder.of.the.be...@gmail.com> wrote:
> Please take a look at the MegaProtoUser and MegaMetaProtoUser code for
> examples of how to create traits that can be mixed into classes.
>
> Does that help?
>
> On Thu, Feb 4, 2010 at 9:58 AM, Mads Hartmann Jensen <mads...@gmail.com>wrote:
>
>
>
>
>
> > hello Jeppe,
>
> > In my project I've got the following three models: A discovery, a Scientist
> > and a lab. The Discovery has been invented by someone, this is either a
> > single scientist or sometimes a lab - This is easily done through
> > inheritance (would create a superclass named source) but I'm not sure how to
> > do this so it maps nicely to the database.
>
> > Scientist and Lab only share one attribute so what I'm most interested in
> > is to be able express that a Discovery has s source that can be either a lab
> > or scientist :)
>
> > Hope this explains my problem more clearly, thanks for the help
>
> > Mads Hartmann
>
> > Sent from my iPhone
>
> > On 04/02/2010, at 18.17, Jeppe Nejsum Madsen <je...@ingolfs.dk> wrote:
>
> >> liftweb+u...@googlegroups.com<liftweb%2Bunsu...@googlegroups.com >
> >> .
> >> For more options, visit this group at
> >>http://groups.google.com/group/liftweb?hl=en.
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Lift" group.
> > To post to this group, send email to lif...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > liftweb+u...@googlegroups.com<liftweb%2Bunsu...@googlegroups.com >
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/liftweb?hl=en.
>
> --
> Lift, the simply functional web frameworkhttp://liftweb.net
> Beginning Scalahttp://www.apress.com/book/view/1430219890
-------------------------------------
Mads Hartmann<mad...@gmail.com> wrote:
/------------------------------- code
self: T =>
def getSingleton = Scientist
def getSingleton = Lab
/------------------------------- code ends
/------------------------------- code starts again
def getSingleton = Discovery
/------------------------------- code ends
Thanks,
Mads Hartmann Jensen
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
If you have a solution I would love to hear it :)
On Feb 5, 1:52 am, Naftoli Gugenheim <naftoli...@gmail.com> wrote:
> Does my approach not work?
>
> -------------------------------------
>
-Ross
-------------------------------------
On Feb 5, 6:56 pm, Naftoli Gugenheim <naftoli...@gmail.com> wrote:
> Peek --www.getpeek.com
> Please forward any bad messages to feedb...@getpeek.com
>
> -------------------------------------
>
> Ross Mellgren<dri...@gmail.com> wrote:
>
> This is actually fairly common that messages Naftoli sends are empty, or don't get threaded onto the original discussion, or formatting comes out funny. Naftoli, what email client are you using?
>
> -Ross
>
> On Feb 5, 2010, at 1:49 AM, Mads Hartmann wrote:
>
>
>
>
>
> > Hey Naftoli,
> > I think something might have broken your first message, It's a blank
> > message if you view it through the web-interface:
> >http://groups.google.com/group/liftweb/browse_thread/thread/e2317e5db...
Sorry for the brevity, if unclear please ask.
-------------------------------------
Mads Hartmann<mad...@gmail.com> wrote:
I don't think I fully understand how to implement any of the suggested
solutions, if you have the time I would love a code example :)
Thanks a lot,
Mads Hartmann Jensen
On Feb 5, 7:34 pm, Naftoli Gugenheim <naftoli...@gmail.com> wrote:
> Basically, either use two protected LongMappedMappers and a public getter/setter that takes a boolean into account in both directions; or use a MappedLong, with
> def obj = whicheverLookUpTable.find(this.is)
> and
> override def set(s: Source) = s match ...
>
> Sorry for the brevity, if unclear please ask.
>
> -------------------------------------
>
object isLab extends MappedBoolean(this)
1.
def source: Box[Source] = if(isLab.is) lab.obj else scientist.obj
def source_=(s: Source) = s match {
case l: Lab => isLab(true); lab(l)
// same for scientist
}
2.
object source extends MappedLong {
def obj = if(isLab) Lab.find(is) else Scientist.find(is)
def obj_=(s: Source) = s match {
case _: Lab => set(s.id)
// same for scientist
}
The advantage of 1 is database FK constraints.
The advantage of 2 is fewer fields.
-------------------------------------
Mads Hartmann<mad...@gmail.com> wrote:
On Feb 5, 8:15 pm, Naftoli Gugenheim <naftoli...@gmail.com> wrote:
> Not tested or compiled
>
> object isLab extends MappedBoolean(this)
> 1.
> def source: Box[Source] = if(isLab.is) lab.obj else scientist.obj
> def source_=(s: Source) = s match {
> case l: Lab => isLab(true); lab(l)
> // same for scientist
>
> }
>
> 2.
> object source extends MappedLong {
> def obj = if(isLab) Lab.find(is) else Scientist.find(is)
> def obj_=(s: Source) = s match {
> case _: Lab => set(s.id)
> // same for scientist
>
> }
>
> The advantage of 1 is database FK constraints.
> The advantage of 2 is fewer fields.
>
> -------------------------------------
>
> ...
>
> read more »