How do I access the fields of a link-table with Lift Mapper?

31 views
Skip to first unread message

Jacobus

unread,
Oct 11, 2012, 2:33:01 PM10/11/12
to lif...@googlegroups.com
Hi there,

I've asked this question on stack-overflow (http://stackoverflow.com/q/12843590/828757). I hope the lift forum will be able to give me some guidance:

From the Lift-Web Mapper model below, how do I access the fields under AssignmentformLink?

    object TForm extends TForm with LongKeyedMetaMapper[TForm]
   
    class TForm extends LongKeyedMapper[TForm] with IdPK with ManyToMany {
      def getSingleton = TForm
   
      object label extends MappedString(this, 40)
   
      object pattern extends MappedString(this, 200)
   
      object assignments extends MappedManyToMany(
          AssignmentformLink, AssignmentformLink.assignment, AssignmentformLink.form, TForm)
   
    }
   
    object AssignmentformLink extends AssignmentformLink with LongKeyedMetaMapper[AssignmentformLink] {
      override def dbIndexes = Index(form, assignment) :: super.dbIndexes
    }
   
    class AssignmentformLink extends LongKeyedMapper[AssignmentformLink] with IdPK {
      def getSingleton = AssignmentformLink
   
      object form extends MappedLongForeignKey(this, TForm)
   
      object assignment extends MappedLongForeignKey(this, Assignment)
   
      object order extends MappedInt(this)
   
      object readonly extends MappedBoolean(this)
   
      object required extends MappedBoolean(this)
   
      object visible extends MappedBoolean(this)
   
    }
   
    object Assignment extends Assignment with LongKeyedMetaMapper[Assignment]
   
    class Assignment extends LongKeyedMapper[Assignment] with IdPK with ManyToMany {
      def getSingleton = Assignment
   
      object id_parent extends MappedLong(this)
   
      object label extends MappedString(this, 40)
   
      object order extends MappedInt(this)
   
      object guard extends MappedString(this, 200)
   
      object forms extends MappedManyToMany(
          AssignmentformLink, AssignmentformLink.assignment, AssignmentformLink.form, TForm)
   
    }

To get an assignmet and the forms linked to it, you do this:

    val assignments = Assignments.find(By(Assignment.id, 123))
  
    assignments match {
      case Full(as) => {
        val forms = as.forms
    .....

But I have no idea how to navigate to the `order, readonly, required...` fields under `AssignmentformLink`.

I realise I can search for the link manually, ie. `AssignmentformLink.find(By(form...),By(assignment...))`, but this will result in inefficient code and really misses the point of using objects.

I need to be able to *navigate* from the form to the link table's fields.

Kind regards,
Jacobus

Diego Medina

unread,
Oct 11, 2012, 3:00:30 PM10/11/12
to lif...@googlegroups.com
Hi, You don;t have your ManyToMany relationship defined right (or
maybe I'm missing something)

from here:


class Assignment extends LongKeyedMapper[Assignment] with IdPK with ManyToMany {
def getSingleton = Assignment

object id_parent extends MappedLong(this)

object label extends MappedString(this, 40)

object order extends MappedInt(this)

object guard extends MappedString(this, 200)

object forms extends MappedManyToMany(
AssignmentformLink, AssignmentformLink.assignment,
AssignmentformLink.form, TForm
)

}



these lines

object forms extends MappedManyToMany(
AssignmentformLink, AssignmentformLink.assignment,
AssignmentformLink.form, TForm
)

one of the two tables there should the the class enclosing the object
forms, maybe, in SQL, how are your tables related, so I can better
help you, also, you may want to look at this wiki page (which I find
very useful), about mapper and manyTOMany:


https://www.assembla.com/spaces/liftweb/wiki/mapper#manytomany


Thanks

Diego
> --
> --
> Lift, the simply functional web framework: http://liftweb.net
> Code: http://github.com/lift
> Discussion: http://groups.google.com/group/liftweb
> Stuck? Help us help you:
> https://www.assembla.com/wiki/show/liftweb/Posting_example_code
>
>
>



--
Diego Medina
Lift/Scala Developer
di...@fmpwizard.com
http://www.fmpwizard.com

Jacobus

unread,
Oct 11, 2012, 4:27:39 PM10/11/12
to lif...@googlegroups.com
Hi,

Thanks for the advice and link. The mapping as I have described it does work, but I don't know how to get to the link-table's fields. It must be possible.... I hope :-p

Kind regards,
Jacobus

Diego Medina

unread,
Oct 11, 2012, 4:48:34 PM10/11/12
to lif...@googlegroups.com
ok, so, from where do you want to access the fields in
AssignmentformLink? What is your starting point?

Thanks

Diego

Diego Medina

unread,
Oct 11, 2012, 4:57:11 PM10/11/12
to lif...@googlegroups.com
ok, I looked over your post again, you have extra fields on your link table,

object order extends MappedInt(this)

object readonly extends MappedBoolean(this)

object required extends MappedBoolean(this)

object visible extends MappedBoolean(this)



the point of the AssignmentformLink table is to have only 3 columns, a
row ID, an ID for the Forms table and an ID for the Assignment table,
you can, as you have, add more fields to it, but this isn;t correct,
from an SQL point of view.

I imagine that an "assignment" is the one that should have the fields
orde/readonly/require/visible columns, and is it a OneToMany? can any
assignment have any number of forms, and then any form can have any
number of assignments?


P.S. Emails like this are why you most likely don;t get answers on
StackOverflow, questions about Lift usually need a few back and forth,
which are not really the way things are done on StackOverflow.

Thanks

Diego

Jacobus

unread,
Oct 11, 2012, 5:37:12 PM10/11/12
to lif...@googlegroups.com
Hi,

Thanks again for trying to help.

Having additional fields in link tables are actually quite a common thing. Imagine a link table that binds UserRoles to Files in your directory. Any user role may be linked to any file, but the link describes if the user in that role edit, read or delete the file.

I am able to solve my problem by manually looking up the form id and then the assignment id, and then use those to look up the AssignementformLink, but that gets dirtry really quickly and creates additional round trips to the database.

Regards,
Jacobus

Diego Medina

unread,
Oct 11, 2012, 8:24:11 PM10/11/12
to lif...@googlegroups.com
The solution you came up with is the only way, as you noted, it is not
pretty, because that middle table isn;t supposed to be used like that
(some ORM don;t even ask you to define such table, so they almost
invisible).

So I assume you cannot change your db design at this point, if that
isn;t the case, there are other designs you can use, which would
result in cleaner code, but again, what you have works, so that may be
fine for now.

Thanks

Diego

Naftoli Gugenheim

unread,
Oct 12, 2012, 4:53:33 PM10/12/12
to lif...@googlegroups.com
You can do assignments.joins to get a List[TheJoinTable]. However you may prefer to use multiple OneToManys instead.

TableA(id, field) -- TableB(id, field, tableAId, tableCId) -- TableC(id, field)

You can look at the above as a many-to-many between table A and table C. But in another sense, it's a one-to-many between A and B, and another one-to-many between C and B.


On Thu, Oct 11, 2012 at 2:33 PM, Jacobus <jacobus...@gmail.com> wrote:

Jacobus

unread,
Oct 15, 2012, 4:17:01 AM10/15/12
to lif...@googlegroups.com
Thanks for the advice. I'll give it a go.
Reply all
Reply to author
Forward
0 new messages