[Lift] Re: New features
Anyone have code showing this in action as it were? On Aug 6, 8:39 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Oh, I think I know what the problem is. I think I should classify it as a bug. Since you're adding a Role that isn't saved yet, and ManyToMany tracks the children via the join table, it can't access the child. As a workaround save the Role before adding it, although the need to do so is against the idea of ManyToMany and OneToMany. I will see what I can do, G-d willing. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli Gugenheim naftoli...@gmail.com wrote: I'll try. By the way, as per my correction, you can implement list the regular way without ModelView, and just use ModelSnippet's load function in your edit link or button, passing it the User instance. - glenngl...@exmbly.com wrote: Naftoli, I fixed my code per your comments and now I can edit and remove users from a list, as long as I populate the list with ModelView instances, as you said. As for the docs, this step was not clear to me at all. I just assumed that the list was just populated with User entities and the view in the ModelSnippet was instantiated with the selected User on each request. It sounds like your plate is pretty full, so I won't expect much, but sometime soon, could you provide an example, or improved docs, for using TableEditor and its related ItemsList trait. Thanks for all. Glenn... On Aug 5, 9:18 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Correction: ModelSnippet.load takes the actual Mapper instance, not the ModelView wrapper. - Naftoli Gugenheimnaftoli...@gmail.com wrote: To answer your immediate question, the listing should not refer to the snippet's view but new ModelView instances for each entity. Then editAction is shorthand for the snippet's link method with a callback to call load on the ModelView. To set the snippet's view's entity, either call load on the snippet with the other ModelView, or call load on the other ModelView (or just set its entity directly). As far as documentation, please tell me what scaladocs need what clarification. Thanks. - glenngl...@exmbly.com wrote: Naftoli, Functional programming systems are notoriously difficult to document. The only way to really know what's going on is to meticulously trace through the source. But that requires time-consuming trial and error coding. So, without clear examples demonstrating exactly what
[Lift] Re: New features
This meaning the problem, or meaning ManyToMany? It's pretty simple to use. You're mapper should extend ManyToMany, and you should have a field: object m2m extends MappedManyToMany(.../*the two MetaMappers and foreign keys, see the docs/source*/) Then you can treat m2m as a Buffer, adding and deleting children. Call save on the mapper or m2m to propogate the adding/deleting to the database, and refresh to reset its contents to reflect the database. However, as noted currently the children must be saved before they are added. This is not the case for OneToMany, and for ManyToMany it should not be a problem because usually the children exist independently of the parent--that's why they can have 0 or 1 or more parents. - Randinnrand...@gmail.com wrote: Anyone have code showing this in action as it were? On Aug 6, 8:39 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Oh, I think I know what the problem is. I think I should classify it as a bug. Since you're adding a Role that isn't saved yet, and ManyToMany tracks the children via the join table, it can't access the child. As a workaround save the Role before adding it, although the need to do so is against the idea of ManyToMany and OneToMany. I will see what I can do, G-d willing. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli Gugenheim naftoli...@gmail.com wrote: I'll try. By the way, as per my correction, you can implement list the regular way without ModelView, and just use ModelSnippet's load function in your edit link or button, passing it the User instance. - glenngl...@exmbly.com wrote: Naftoli, I fixed my code per your comments and now I can edit and remove users from a list, as long as I populate the list with ModelView instances, as you said. As for the docs, this step was not clear to me at all. I just assumed that the list was just populated with User entities and the view in the ModelSnippet was instantiated with the selected User on each request. It sounds like your plate is pretty full, so I won't expect much, but sometime soon, could you provide an example, or improved docs, for using TableEditor and its related ItemsList trait. Thanks for all. Glenn... On Aug 5, 9:18 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Correction: ModelSnippet.load takes the actual Mapper instance, not the ModelView wrapper. - Naftoli Gugenheimnaftoli...@gmail.com wrote: To answer your immediate question, the listing should not refer to the
[Lift] Re: New features
I have a working example of ManyToMany that adds roles to users. I would be happy to share my work but I have an aversion to github. I don't like it, It's a slower-than- molasses interface. It's buggy and user-hostile in my opinion. I'm looking for an alternative to make it public. Any suggestions would be appreciated. Glenn... On Aug 25, 7:08 am, Naftoli Gugenheim naftoli...@gmail.com wrote: This meaning the problem, or meaning ManyToMany? It's pretty simple to use. You're mapper should extend ManyToMany, and you should have a field: object m2m extends MappedManyToMany(.../*the two MetaMappers and foreign keys, see the docs/source*/) Then you can treat m2m as a Buffer, adding and deleting children. Call save on the mapper or m2m to propogate the adding/deleting to the database, and refresh to reset its contents to reflect the database. However, as noted currently the children must be saved before they are added. This is not the case for OneToMany, and for ManyToMany it should not be a problem because usually the children exist independently of the parent--that's why they can have 0 or 1 or more parents. - Randinnrand...@gmail.com wrote: Anyone have code showing this in action as it were? On Aug 6, 8:39 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Oh, I think I know what the problem is. I think I should classify it as a bug. Since you're adding a Role that isn't saved yet, and ManyToMany tracks the children via the join table, it can't access the child. As a workaround save the Role before adding it, although the need to do so is against the idea of ManyToMany and OneToMany. I will see what I can do, G-d willing. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli Gugenheim naftoli...@gmail.com wrote: I'll try. By the way, as per my correction, you can implement list the regular way without ModelView, and just use ModelSnippet's load function in your edit link or button, passing it the User instance. - glenngl...@exmbly.com wrote: Naftoli, I fixed my code per your comments and now I can edit and remove users from a list, as long as I populate the list with ModelView instances, as you said. As for the docs, this step was not clear to me at all. I just assumed that the list was just populated with User entities and the view in the ModelSnippet was instantiated with the selected User on each request. It sounds like your plate is pretty full, so I won't expect much, but
[Lift] Re: New features
Google code? Sourceforge? ProjectLocker? There are a lot of choices... On Tue, Aug 25, 2009 at 12:37 PM, glenngl...@exmbly.com wrote: I have a working example of ManyToMany that adds roles to users. I would be happy to share my work but I have an aversion to github. I don't like it, It's a slower-than- molasses interface. It's buggy and user-hostile in my opinion. I'm looking for an alternative to make it public. Any suggestions would be appreciated. Glenn... On Aug 25, 7:08 am, Naftoli Gugenheim naftoli...@gmail.com wrote: This meaning the problem, or meaning ManyToMany? It's pretty simple to use. You're mapper should extend ManyToMany, and you should have a field: object m2m extends MappedManyToMany(.../*the two MetaMappers and foreign keys, see the docs/source*/) Then you can treat m2m as a Buffer, adding and deleting children. Call save on the mapper or m2m to propogate the adding/deleting to the database, and refresh to reset its contents to reflect the database. However, as noted currently the children must be saved before they are added. This is not the case for OneToMany, and for ManyToMany it should not be a problem because usually the children exist independently of the parent--that's why they can have 0 or 1 or more parents. - Randinnrand...@gmail.com wrote: Anyone have code showing this in action as it were? On Aug 6, 8:39 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Oh, I think I know what the problem is. I think I should classify it as a bug. Since you're adding a Role that isn't saved yet, and ManyToMany tracks the children via the join table, it can't access the child. As a workaround save the Role before adding it, although the need to do so is against the idea of ManyToMany and OneToMany. I will see what I can do, G-d willing. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli Gugenheim naftoli...@gmail.com wrote: I'll try. By the way, as per my correction, you can implement list the regular way without ModelView, and just use ModelSnippet's load function in your edit link or button, passing it the User instance. - glenngl...@exmbly.com wrote: Naftoli, I fixed my code per your comments and now I can edit and remove users from a list, as long as I populate the list with ModelView instances, as you said. As for the docs, this step was not clear to me at all. I just assumed that the list was just populated with User entities and the view in the
[Lift] Re: New features
Well, I managed to upload to github. Here is the repository: git://github.com/glennSilverman/UserMon.git Any feedback is appreciated. Glenn... On Aug 25, 10:43 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Google code? Sourceforge? ProjectLocker? There are a lot of choices... On Tue, Aug 25, 2009 at 12:37 PM, glenngl...@exmbly.com wrote: I have a working example of ManyToMany that adds roles to users. I would be happy to share my work but I have an aversion to github. I don't like it, It's a slower-than- molasses interface. It's buggy and user-hostile in my opinion. I'm looking for an alternative to make it public. Any suggestions would be appreciated. Glenn... On Aug 25, 7:08 am, Naftoli Gugenheim naftoli...@gmail.com wrote: This meaning the problem, or meaning ManyToMany? It's pretty simple to use. You're mapper should extend ManyToMany, and you should have a field: object m2m extends MappedManyToMany(.../*the two MetaMappers and foreign keys, see the docs/source*/) Then you can treat m2m as a Buffer, adding and deleting children. Call save on the mapper or m2m to propogate the adding/deleting to the database, and refresh to reset its contents to reflect the database. However, as noted currently the children must be saved before they are added. This is not the case for OneToMany, and for ManyToMany it should not be a problem because usually the children exist independently of the parent--that's why they can have 0 or 1 or more parents. - Randinnrand...@gmail.com wrote: Anyone have code showing this in action as it were? On Aug 6, 8:39 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Oh, I think I know what the problem is. I think I should classify it as a bug. Since you're adding a Role that isn't saved yet, and ManyToMany tracks the children via the join table, it can't access the child. As a workaround save the Role before adding it, although the need to do so is against the idea of ManyToMany and OneToMany. I will see what I can do, G-d willing. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli Gugenheim naftoli...@gmail.com wrote: I'll try. By the way, as per my correction, you can implement list the regular way without ModelView, and just use ModelSnippet's load function in your edit link or button, passing it the User instance. - glenngl...@exmbly.com wrote:
[Lift] Re: New features
Great! Thank you both for you help. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: New features
It looks like some .is's need to be explicit. I wonder if the implicit doesn't apply now that it's using member types? David, if you choose to volunteer to add .is to references to primaryKeyField it will get on github sooner than if I do it, but I can do it if you don't. - glenngl...@exmbly.com wrote: David, I'm using your new ManyToMany trait and ran across this error: Message: java.lang.ClassCastException: net.liftweb.mapper.ProtoUser$id $ cannot be cast to java.lang.Long scala.runtime.BoxesRunTime.unboxToLong(Unknown Source) net.liftweb.mapper.MappedLong.real_i_set_$bang(MappedLong.scala:223) net.liftweb.mapper.MappedField$class.i_set_$bang(MappedField.scala: 449) net.liftweb.mapper.MappedLong.i_set_$bang(MappedLong.scala:223) net.liftweb.mapper.MappedField$class.set(MappedField.scala:429) net.liftweb.mapper.MappedLong.set(MappedLong.scala:223) net.liftweb.mapper.ManyToMany$MappedManyToMany.own(ManyToMany.scala: 78) My code that generates the error is: entity.roles += r where entity is a User and roles is the MappedManyToMany object in User. Glenn... On Aug 8, 10:35 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Thanks, David. Glenn, as far as the issue of adding unsaved children, I was thinking about it. If the same Role can be referenced by multiple users, why are you creating Roles at the same time that you are adding them to a User? Shouldn't there be one screen to manage Roles and the User screen would only allow you to add existing Roles? - David Pollakfeeder.of.the.be...@gmail.com wrote: There are dependent types that mirror the parameterized types for Mapper, KeyedMapper, etc. I've updated ManyToMany to use the dependent types... it should eliminate the need to have the type parameters. If it breaks thing, please revert the changes. On Thu, Aug 6, 2009 at 9:55 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: In your use case it can only be Long and User. But there has to be a type parameter because other people might have a String key and a Request mapper. And the contents of ManyToMany have to be type safe to enforce their consistency with however the user of ManyToMany wants them to use it. So I think what you want is that the compiler should figure out that since you're using it with a KeyedMapper[Long, User], which is ManyToMany's T : KeyedMapper[K,T], and ManyToMany extends KeyedMapper[K,T] and it has a self type of T, and therefore it would be a compiler error to write anything besides Long and User, therefore you must want to use Long and User and they should be inferred. I could certainly hear that, although I'm not much of a type theorist. So feel free to open an enhancement ticket on Scala's Trac! :) If I understood correctly... On Thu, Aug 6, 2009 at 12:43 PM, glenn gl...@exmbly.com wrote: Naftoli, As I said at the outset, this is really beyond my expertise. But I think it's too broad and maybe, even unnecessary. In my example, K can only be one type, Long, and T can only be of type User. Anything else, and the compiler can't be guaranteed to catch it, but try running the application and you get things like stack overflow errors. How you would fix this is beyond me. All you can really do, at this point, is make sure to include these kinds of restrictions in the docs. Glenn... On Aug 6, 9:33 am, Naftoli Gugenheim naftoli...@gmail.com wrote: It's too broad, or it's too restrictive/unnecessary? I'm confused, you seem to imply both.If it's too broad, tell me why. But if you want to know why it needs the type parameter, it's because it has to use the type parameter in its implentation -- just count how many times its source code uses it! And if you want to know why the compiler can't infer it or be told to infer it... that's another issue. But if passing a type that creates a conflicting inheritance causes a compiler crash, that's not something I can help. :) Regards. On Thu, Aug 6, 2009 at 12:26 PM, glenn gl...@exmbly.com wrote: Naftoli, At the risk of discussing something obviously beyond my pay grade, isn't the real issue Scala traits and the use of parameterized types. The ManyToMany trait is defined as: trait ManyToMany[K,T:KeyedMapper[K, T]] But this isn't really correct,is it, the parameter is too broad, and that leads to a lot of the confusion and results in the need for unnecessary documentation. When you think about it, why all the duplication? Why do I need to write my User entity as: class User extends MegaProtoUser[User] with ManyToMany[Long,User] when we all know that this would be much cleaner: class User extends MegaProtoUser[User] with ManyToMany. But traits aren't like interfaces. They have implementation and would need to know
[Lift] Re: New features
David, I'm using your new ManyToMany trait and ran across this error: Message: java.lang.ClassCastException: net.liftweb.mapper.ProtoUser$id $ cannot be cast to java.lang.Long scala.runtime.BoxesRunTime.unboxToLong(Unknown Source) net.liftweb.mapper.MappedLong.real_i_set_$bang(MappedLong.scala:223) net.liftweb.mapper.MappedField$class.i_set_$bang(MappedField.scala: 449) net.liftweb.mapper.MappedLong.i_set_$bang(MappedLong.scala:223) net.liftweb.mapper.MappedField$class.set(MappedField.scala:429) net.liftweb.mapper.MappedLong.set(MappedLong.scala:223) net.liftweb.mapper.ManyToMany$MappedManyToMany.own(ManyToMany.scala: 78) My code that generates the error is: entity.roles += r where entity is a User and roles is the MappedManyToMany object in User. Glenn... On Aug 8, 10:35 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Thanks, David. Glenn, as far as the issue of adding unsaved children, I was thinking about it. If the same Role can be referenced by multiple users, why are you creating Roles at the same time that you are adding them to a User? Shouldn't there be one screen to manage Roles and the User screen would only allow you to add existing Roles? - David Pollakfeeder.of.the.be...@gmail.com wrote: There are dependent types that mirror the parameterized types for Mapper, KeyedMapper, etc. I've updated ManyToMany to use the dependent types... it should eliminate the need to have the type parameters. If it breaks thing, please revert the changes. On Thu, Aug 6, 2009 at 9:55 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: In your use case it can only be Long and User. But there has to be a type parameter because other people might have a String key and a Request mapper. And the contents of ManyToMany have to be type safe to enforce their consistency with however the user of ManyToMany wants them to use it. So I think what you want is that the compiler should figure out that since you're using it with a KeyedMapper[Long, User], which is ManyToMany's T : KeyedMapper[K,T], and ManyToMany extends KeyedMapper[K,T] and it has a self type of T, and therefore it would be a compiler error to write anything besides Long and User, therefore you must want to use Long and User and they should be inferred. I could certainly hear that, although I'm not much of a type theorist. So feel free to open an enhancement ticket on Scala's Trac! :) If I understood correctly... On Thu, Aug 6, 2009 at 12:43 PM, glenn gl...@exmbly.com wrote: Naftoli, As I said at the outset, this is really beyond my expertise. But I think it's too broad and maybe, even unnecessary. In my example, K can only be one type, Long, and T can only be of type User. Anything else, and the compiler can't be guaranteed to catch it, but try running the application and you get things like stack overflow errors. How you would fix this is beyond me. All you can really do, at this point, is make sure to include these kinds of restrictions in the docs. Glenn... On Aug 6, 9:33 am, Naftoli Gugenheim naftoli...@gmail.com wrote: It's too broad, or it's too restrictive/unnecessary? I'm confused, you seem to imply both.If it's too broad, tell me why. But if you want to know why it needs the type parameter, it's because it has to use the type parameter in its implentation -- just count how many times its source code uses it! And if you want to know why the compiler can't infer it or be told to infer it... that's another issue. But if passing a type that creates a conflicting inheritance causes a compiler crash, that's not something I can help. :) Regards. On Thu, Aug 6, 2009 at 12:26 PM, glenn gl...@exmbly.com wrote: Naftoli, At the risk of discussing something obviously beyond my pay grade, isn't the real issue Scala traits and the use of parameterized types. The ManyToMany trait is defined as: trait ManyToMany[K,T:KeyedMapper[K, T]] But this isn't really correct,is it, the parameter is too broad, and that leads to a lot of the confusion and results in the need for unnecessary documentation. When you think about it, why all the duplication? Why do I need to write my User entity as: class User extends MegaProtoUser[User] with ManyToMany[Long,User] when we all know that this would be much cleaner: class User extends MegaProtoUser[User] with ManyToMany. But traits aren't like interfaces. They have implementation and would need to know something about the parent class they are attached to - and how would you accomplish that (reflection, maybe). This is more a Scala issue than a Lift one, I think. Glenn... On Aug 5, 8:24 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Building causes a stack overflow? So the question is, is it the resident
[Lift] Re: New features
I've got negative available time. Sorry. On Mon, Aug 10, 2009 at 1:28 PM, Naftoli Gugenheim naftoli...@gmail.comwrote: It looks like some .is's need to be explicit. I wonder if the implicit doesn't apply now that it's using member types? David, if you choose to volunteer to add .is to references to primaryKeyField it will get on github sooner than if I do it, but I can do it if you don't. - glenngl...@exmbly.com wrote: David, I'm using your new ManyToMany trait and ran across this error: Message: java.lang.ClassCastException: net.liftweb.mapper.ProtoUser$id $ cannot be cast to java.lang.Long scala.runtime.BoxesRunTime.unboxToLong(Unknown Source) net.liftweb.mapper.MappedLong.real_i_set_$bang(MappedLong.scala:223) net.liftweb.mapper.MappedField$class.i_set_$bang(MappedField.scala: 449) net.liftweb.mapper.MappedLong.i_set_$bang(MappedLong.scala:223) net.liftweb.mapper.MappedField$class.set(MappedField.scala:429) net.liftweb.mapper.MappedLong.set(MappedLong.scala:223) net.liftweb.mapper.ManyToMany$MappedManyToMany.own(ManyToMany.scala: 78) My code that generates the error is: entity.roles += r where entity is a User and roles is the MappedManyToMany object in User. Glenn... On Aug 8, 10:35 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Thanks, David. Glenn, as far as the issue of adding unsaved children, I was thinking about it. If the same Role can be referenced by multiple users, why are you creating Roles at the same time that you are adding them to a User? Shouldn't there be one screen to manage Roles and the User screen would only allow you to add existing Roles? - David Pollakfeeder.of.the.be...@gmail.com wrote: There are dependent types that mirror the parameterized types for Mapper, KeyedMapper, etc. I've updated ManyToMany to use the dependent types... it should eliminate the need to have the type parameters. If it breaks thing, please revert the changes. On Thu, Aug 6, 2009 at 9:55 AM, Naftoli Gugenheim naftoli...@gmail.com wrote: In your use case it can only be Long and User. But there has to be a type parameter because other people might have a String key and a Request mapper. And the contents of ManyToMany have to be type safe to enforce their consistency with however the user of ManyToMany wants them to use it. So I think what you want is that the compiler should figure out that since you're using it with a KeyedMapper[Long, User], which is ManyToMany's T : KeyedMapper[K,T], and ManyToMany extends KeyedMapper[K,T] and it has a self type of T, and therefore it would be a compiler error to write anything besides Long and User, therefore you must want to use Long and User and they should be inferred. I could certainly hear that, although I'm not much of a type theorist. So feel free to open an enhancement ticket on Scala's Trac! :) If I understood correctly... On Thu, Aug 6, 2009 at 12:43 PM, glenn gl...@exmbly.com wrote: Naftoli, As I said at the outset, this is really beyond my expertise. But I think it's too broad and maybe, even unnecessary. In my example, K can only be one type, Long, and T can only be of type User. Anything else, and the compiler can't be guaranteed to catch it, but try running the application and you get things like stack overflow errors. How you would fix this is beyond me. All you can really do, at this point, is make sure to include these kinds of restrictions in the docs. Glenn... On Aug 6, 9:33 am, Naftoli Gugenheim naftoli...@gmail.com wrote: It's too broad, or it's too restrictive/unnecessary? I'm confused, you seem to imply both.If it's too broad, tell me why. But if you want to know why it needs the type parameter, it's because it has to use the type parameter in its implentation -- just count how many times its source code uses it! And if you want to know why the compiler can't infer it or be told to infer it... that's another issue. But if passing a type that creates a conflicting inheritance causes a compiler crash, that's not something I can help. :) Regards. On Thu, Aug 6, 2009 at 12:26 PM, glenn gl...@exmbly.com wrote: Naftoli, At the risk of discussing something obviously beyond my pay grade, isn't the real issue Scala traits and the use of parameterized types. The ManyToMany trait is defined as: trait ManyToMany[K,T:KeyedMapper[K, T]] But this isn't really correct,is it, the parameter is too broad, and that leads to a lot of the confusion and results in the need for unnecessary documentation. When you think about it, why all the duplication? Why do I need to write my User entity as: class User extends MegaProtoUser[User]
[Lift] Re: New features
Okay, done. Wait until hudson builds it. - glenngl...@exmbly.com wrote: I assume this could take a while to fix. Meantime, could someone revert 1.1-SNAPSHOT back to before this change? Thanks Glenn... On Aug 10, 1:43 pm, David Pollak feeder.of.the.be...@gmail.com wrote: I've got negative available time. Sorry. On Mon, Aug 10, 2009 at 1:28 PM, Naftoli Gugenheim naftoli...@gmail.comwrote: It looks like some .is's need to be explicit. I wonder if the implicit doesn't apply now that it's using member types? David, if you choose to volunteer to add .is to references to primaryKeyField it will get on github sooner than if I do it, but I can do it if you don't. - glenngl...@exmbly.com wrote: David, I'm using your new ManyToMany trait and ran across this error: Message: java.lang.ClassCastException: net.liftweb.mapper.ProtoUser$id $ cannot be cast to java.lang.Long scala.runtime.BoxesRunTime.unboxToLong(Unknown Source) net.liftweb.mapper.MappedLong.real_i_set_$bang(MappedLong.scala:223) net.liftweb.mapper.MappedField$class.i_set_$bang(MappedField.scala: 449) net.liftweb.mapper.MappedLong.i_set_$bang(MappedLong.scala:223) net.liftweb.mapper.MappedField$class.set(MappedField.scala:429) net.liftweb.mapper.MappedLong.set(MappedLong.scala:223) net.liftweb.mapper.ManyToMany$MappedManyToMany.own(ManyToMany.scala: 78) My code that generates the error is: entity.roles += r where entity is a User and roles is the MappedManyToMany object in User. Glenn... On Aug 8, 10:35 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Thanks, David. Glenn, as far as the issue of adding unsaved children, I was thinking about it. If the same Role can be referenced by multiple users, why are you creating Roles at the same time that you are adding them to a User? Shouldn't there be one screen to manage Roles and the User screen would only allow you to add existing Roles? - David Pollakfeeder.of.the.be...@gmail.com wrote: There are dependent types that mirror the parameterized types for Mapper, KeyedMapper, etc. I've updated ManyToMany to use the dependent types... it should eliminate the need to have the type parameters. If it breaks thing, please revert the changes. On Thu, Aug 6, 2009 at 9:55 AM, Naftoli Gugenheim naftoli...@gmail.com wrote: In your use case it can only be Long and User. But there has to be a type parameter because other people might have a String key and a Request mapper. And the contents of ManyToMany have to be type safe to enforce their consistency with however the user of ManyToMany wants them to use it. So I think what you want is that the compiler should figure out that since you're using it with a KeyedMapper[Long, User], which is ManyToMany's T : KeyedMapper[K,T], and ManyToMany extends KeyedMapper[K,T] and it has a self type of T, and therefore it would be a compiler error to write anything besides Long and User, therefore you must want to use Long and User and they should be inferred. I could certainly hear that, although I'm not much of a type theorist. So feel free to open an enhancement ticket on Scala's Trac! :) If I understood correctly... On Thu, Aug 6, 2009 at 12:43 PM, glenn gl...@exmbly.com wrote: Naftoli, As I said at the outset, this is really beyond my expertise. But I think it's too broad and maybe, even unnecessary. In my example, K can only be one type, Long, and T can only be of type User. Anything else, and the compiler can't be guaranteed to catch it, but try running the application and you get things like stack overflow errors. How you would fix this is beyond me. All you can really do, at this point, is make sure to include these kinds of restrictions in the docs. Glenn... On Aug 6, 9:33 am, Naftoli Gugenheim naftoli...@gmail.com wrote: It's too broad, or it's too restrictive/unnecessary? I'm confused, you seem to imply both.If it's too broad, tell me why. But if you want to know why it needs the type parameter, it's because it has to use the type parameter in its implentation -- just count how many times its source code uses it! And if you want to know why the compiler can't infer it or be told to infer it... that's another issue. But if passing a type that creates a conflicting inheritance causes a compiler crash, that's not something I can help. :) Regards. On Thu, Aug 6, 2009 at 12:26 PM, glenn gl...@exmbly.com wrote: Naftoli, At the risk of discussing something obviously beyond my pay grade, isn't the real issue Scala traits and the use of parameterized types. The ManyToMany
[Lift] Re: New features
Thanks, David. Glenn, as far as the issue of adding unsaved children, I was thinking about it. If the same Role can be referenced by multiple users, why are you creating Roles at the same time that you are adding them to a User? Shouldn't there be one screen to manage Roles and the User screen would only allow you to add existing Roles? - David Pollakfeeder.of.the.be...@gmail.com wrote: There are dependent types that mirror the parameterized types for Mapper, KeyedMapper, etc. I've updated ManyToMany to use the dependent types... it should eliminate the need to have the type parameters. If it breaks thing, please revert the changes. On Thu, Aug 6, 2009 at 9:55 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: In your use case it can only be Long and User. But there has to be a type parameter because other people might have a String key and a Request mapper. And the contents of ManyToMany have to be type safe to enforce their consistency with however the user of ManyToMany wants them to use it. So I think what you want is that the compiler should figure out that since you're using it with a KeyedMapper[Long, User], which is ManyToMany's T : KeyedMapper[K,T], and ManyToMany extends KeyedMapper[K,T] and it has a self type of T, and therefore it would be a compiler error to write anything besides Long and User, therefore you must want to use Long and User and they should be inferred. I could certainly hear that, although I'm not much of a type theorist. So feel free to open an enhancement ticket on Scala's Trac! :) If I understood correctly... On Thu, Aug 6, 2009 at 12:43 PM, glenn gl...@exmbly.com wrote: Naftoli, As I said at the outset, this is really beyond my expertise. But I think it's too broad and maybe, even unnecessary. In my example, K can only be one type, Long, and T can only be of type User. Anything else, and the compiler can't be guaranteed to catch it, but try running the application and you get things like stack overflow errors. How you would fix this is beyond me. All you can really do, at this point, is make sure to include these kinds of restrictions in the docs. Glenn... On Aug 6, 9:33 am, Naftoli Gugenheim naftoli...@gmail.com wrote: It's too broad, or it's too restrictive/unnecessary? I'm confused, you seem to imply both.If it's too broad, tell me why. But if you want to know why it needs the type parameter, it's because it has to use the type parameter in its implentation -- just count how many times its source code uses it! And if you want to know why the compiler can't infer it or be told to infer it... that's another issue. But if passing a type that creates a conflicting inheritance causes a compiler crash, that's not something I can help. :) Regards. On Thu, Aug 6, 2009 at 12:26 PM, glenn gl...@exmbly.com wrote: Naftoli, At the risk of discussing something obviously beyond my pay grade, isn't the real issue Scala traits and the use of parameterized types. The ManyToMany trait is defined as: trait ManyToMany[K,T:KeyedMapper[K, T]] But this isn't really correct,is it, the parameter is too broad, and that leads to a lot of the confusion and results in the need for unnecessary documentation. When you think about it, why all the duplication? Why do I need to write my User entity as: class User extends MegaProtoUser[User] with ManyToMany[Long,User] when we all know that this would be much cleaner: class User extends MegaProtoUser[User] with ManyToMany. But traits aren't like interfaces. They have implementation and would need to know something about the parent class they are attached to - and how would you accomplish that (reflection, maybe). This is more a Scala issue than a Lift one, I think. Glenn... On Aug 5, 8:24 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Building causes a stack overflow? So the question is, is it the resident compiler or plain scalac also crashes? Or just the presentation compiler? What do you see in the error log view or file? I get compiler crashes very often when doing fancy mapper type related tricks. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54)
[Lift] Re: New features
Naftoli, At the risk of discussing something obviously beyond my pay grade, isn't the real issue Scala traits and the use of parameterized types. The ManyToMany trait is defined as: trait ManyToMany[K,T:KeyedMapper[K, T]] But this isn't really correct,is it, the parameter is too broad, and that leads to a lot of the confusion and results in the need for unnecessary documentation. When you think about it, why all the duplication? Why do I need to write my User entity as: class User extends MegaProtoUser[User] with ManyToMany[Long,User] when we all know that this would be much cleaner: class User extends MegaProtoUser[User] with ManyToMany. But traits aren't like interfaces. They have implementation and would need to know something about the parent class they are attached to - and how would you accomplish that (reflection, maybe). This is more a Scala issue than a Lift one, I think. Glenn... On Aug 5, 8:24 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Building causes a stack overflow? So the question is, is it the resident compiler or plain scalac also crashes? Or just the presentation compiler? What do you see in the error log view or file? I get compiler crashes very often when doing fancy mapper type related tricks. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli Gugenheim naftoli...@gmail.com wrote: I'll try. By the way, as per my correction, you can implement list the regular way without ModelView, and just use ModelSnippet's load function in your edit link or button, passing it the User instance. - glenngl...@exmbly.com wrote: Naftoli, I fixed my code per your comments and now I can edit and remove users from a list, as long as I populate the list with ModelView instances, as you said. As for the docs, this step was not clear to me at all. I just assumed that the list was just populated with User entities and the view in the ModelSnippet was instantiated with the selected User on each request. It sounds like your plate is pretty full, so I won't expect much, but sometime soon, could you provide an example, or improved docs, for using TableEditor and its related ItemsList trait. Thanks for all. Glenn... On Aug 5, 9:18 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Correction: ModelSnippet.load takes the actual Mapper instance, not the ModelView wrapper. - Naftoli Gugenheimnaftoli...@gmail.com wrote: To answer your immediate question, the listing should not refer to the snippet's view but new ModelView instances for each
[Lift] Re: New features
In your use case it can only be Long and User. But there has to be a type parameter because other people might have a String key and a Request mapper. And the contents of ManyToMany have to be type safe to enforce their consistency with however the user of ManyToMany wants them to use it.So I think what you want is that the compiler should figure out that since you're using it with a KeyedMapper[Long, User], which is ManyToMany's T : KeyedMapper[K,T], and ManyToMany extends KeyedMapper[K,T] and it has a self type of T, and therefore it would be a compiler error to write anything besides Long and User, therefore you must want to use Long and User and they should be inferred. I could certainly hear that, although I'm not much of a type theorist. So feel free to open an enhancement ticket on Scala's Trac! :) If I understood correctly... On Thu, Aug 6, 2009 at 12:43 PM, glenn gl...@exmbly.com wrote: Naftoli, As I said at the outset, this is really beyond my expertise. But I think it's too broad and maybe, even unnecessary. In my example, K can only be one type, Long, and T can only be of type User. Anything else, and the compiler can't be guaranteed to catch it, but try running the application and you get things like stack overflow errors. How you would fix this is beyond me. All you can really do, at this point, is make sure to include these kinds of restrictions in the docs. Glenn... On Aug 6, 9:33 am, Naftoli Gugenheim naftoli...@gmail.com wrote: It's too broad, or it's too restrictive/unnecessary? I'm confused, you seem to imply both.If it's too broad, tell me why. But if you want to know why it needs the type parameter, it's because it has to use the type parameter in its implentation -- just count how many times its source code uses it! And if you want to know why the compiler can't infer it or be told to infer it... that's another issue. But if passing a type that creates a conflicting inheritance causes a compiler crash, that's not something I can help. :) Regards. On Thu, Aug 6, 2009 at 12:26 PM, glenn gl...@exmbly.com wrote: Naftoli, At the risk of discussing something obviously beyond my pay grade, isn't the real issue Scala traits and the use of parameterized types. The ManyToMany trait is defined as: trait ManyToMany[K,T:KeyedMapper[K, T]] But this isn't really correct,is it, the parameter is too broad, and that leads to a lot of the confusion and results in the need for unnecessary documentation. When you think about it, why all the duplication? Why do I need to write my User entity as: class User extends MegaProtoUser[User] with ManyToMany[Long,User] when we all know that this would be much cleaner: class User extends MegaProtoUser[User] with ManyToMany. But traits aren't like interfaces. They have implementation and would need to know something about the parent class they are attached to - and how would you accomplish that (reflection, maybe). This is more a Scala issue than a Lift one, I think. Glenn... On Aug 5, 8:24 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Building causes a stack overflow? So the question is, is it the resident compiler or plain scalac also crashes? Or just the presentation compiler? What do you see in the error log view or file? I get compiler crashes very often when doing fancy mapper type related tricks. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname -
[Lift] Re: New features
Naftoli, As I said at the outset, this is really beyond my expertise. But I think it's too broad and maybe, even unnecessary. In my example, K can only be one type, Long, and T can only be of type User. Anything else, and the compiler can't be guaranteed to catch it, but try running the application and you get things like stack overflow errors. How you would fix this is beyond me. All you can really do, at this point, is make sure to include these kinds of restrictions in the docs. Glenn... On Aug 6, 9:33 am, Naftoli Gugenheim naftoli...@gmail.com wrote: It's too broad, or it's too restrictive/unnecessary? I'm confused, you seem to imply both.If it's too broad, tell me why. But if you want to know why it needs the type parameter, it's because it has to use the type parameter in its implentation -- just count how many times its source code uses it! And if you want to know why the compiler can't infer it or be told to infer it... that's another issue. But if passing a type that creates a conflicting inheritance causes a compiler crash, that's not something I can help. :) Regards. On Thu, Aug 6, 2009 at 12:26 PM, glenn gl...@exmbly.com wrote: Naftoli, At the risk of discussing something obviously beyond my pay grade, isn't the real issue Scala traits and the use of parameterized types. The ManyToMany trait is defined as: trait ManyToMany[K,T:KeyedMapper[K, T]] But this isn't really correct,is it, the parameter is too broad, and that leads to a lot of the confusion and results in the need for unnecessary documentation. When you think about it, why all the duplication? Why do I need to write my User entity as: class User extends MegaProtoUser[User] with ManyToMany[Long,User] when we all know that this would be much cleaner: class User extends MegaProtoUser[User] with ManyToMany. But traits aren't like interfaces. They have implementation and would need to know something about the parent class they are attached to - and how would you accomplish that (reflection, maybe). This is more a Scala issue than a Lift one, I think. Glenn... On Aug 5, 8:24 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Building causes a stack overflow? So the question is, is it the resident compiler or plain scalac also crashes? Or just the presentation compiler? What do you see in the error log view or file? I get compiler crashes very often when doing fancy mapper type related tricks. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli
[Lift] Re: New features
There are dependent types that mirror the parameterized types for Mapper, KeyedMapper, etc. I've updated ManyToMany to use the dependent types... it should eliminate the need to have the type parameters. If it breaks thing, please revert the changes. On Thu, Aug 6, 2009 at 9:55 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: In your use case it can only be Long and User. But there has to be a type parameter because other people might have a String key and a Request mapper. And the contents of ManyToMany have to be type safe to enforce their consistency with however the user of ManyToMany wants them to use it. So I think what you want is that the compiler should figure out that since you're using it with a KeyedMapper[Long, User], which is ManyToMany's T : KeyedMapper[K,T], and ManyToMany extends KeyedMapper[K,T] and it has a self type of T, and therefore it would be a compiler error to write anything besides Long and User, therefore you must want to use Long and User and they should be inferred. I could certainly hear that, although I'm not much of a type theorist. So feel free to open an enhancement ticket on Scala's Trac! :) If I understood correctly... On Thu, Aug 6, 2009 at 12:43 PM, glenn gl...@exmbly.com wrote: Naftoli, As I said at the outset, this is really beyond my expertise. But I think it's too broad and maybe, even unnecessary. In my example, K can only be one type, Long, and T can only be of type User. Anything else, and the compiler can't be guaranteed to catch it, but try running the application and you get things like stack overflow errors. How you would fix this is beyond me. All you can really do, at this point, is make sure to include these kinds of restrictions in the docs. Glenn... On Aug 6, 9:33 am, Naftoli Gugenheim naftoli...@gmail.com wrote: It's too broad, or it's too restrictive/unnecessary? I'm confused, you seem to imply both.If it's too broad, tell me why. But if you want to know why it needs the type parameter, it's because it has to use the type parameter in its implentation -- just count how many times its source code uses it! And if you want to know why the compiler can't infer it or be told to infer it... that's another issue. But if passing a type that creates a conflicting inheritance causes a compiler crash, that's not something I can help. :) Regards. On Thu, Aug 6, 2009 at 12:26 PM, glenn gl...@exmbly.com wrote: Naftoli, At the risk of discussing something obviously beyond my pay grade, isn't the real issue Scala traits and the use of parameterized types. The ManyToMany trait is defined as: trait ManyToMany[K,T:KeyedMapper[K, T]] But this isn't really correct,is it, the parameter is too broad, and that leads to a lot of the confusion and results in the need for unnecessary documentation. When you think about it, why all the duplication? Why do I need to write my User entity as: class User extends MegaProtoUser[User] with ManyToMany[Long,User] when we all know that this would be much cleaner: class User extends MegaProtoUser[User] with ManyToMany. But traits aren't like interfaces. They have implementation and would need to know something about the parent class they are attached to - and how would you accomplish that (reflection, maybe). This is more a Scala issue than a Lift one, I think. Glenn... On Aug 5, 8:24 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Building causes a stack overflow? So the question is, is it the resident compiler or plain scalac also crashes? Or just the presentation compiler? What do you see in the error log view or file? I get compiler crashes very often when doing fancy mapper type related tricks. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap
[Lift] Re: New features
Correction: ModelSnippet.load takes the actual Mapper instance, not the ModelView wrapper. - Naftoli Gugenheimnaftoli...@gmail.com wrote: To answer your immediate question, the listing should not refer to the snippet's view but new ModelView instances for each entity. Then editAction is shorthand for the snippet's link method with a callback to call load on the ModelView. To set the snippet's view's entity, either call load on the snippet with the other ModelView, or call load on the other ModelView (or just set its entity directly). As far as documentation, please tell me what scaladocs need what clarification. Thanks. - glenngl...@exmbly.com wrote: Naftoli, Functional programming systems are notoriously difficult to document. The only way to really know what's going on is to meticulously trace through the source. But that requires time-consuming trial and error coding. So, without clear examples demonstrating exactly what you have in mind, I and others in the same boat, could spend days and still not get it right. For example, I tried this: var theUser:User = null val view = new ModelView(theUser, this) def list(ns: NodeSeq): NodeSeq = User.currentUser.map({user = User.findAll.flatMap({u = bind(user, chooseTemplate(user, entry, ns), firstname - Text(u.firstName.is), lastname - Text(u.lastName.is), email - Text(u.email.is), roles - u.roles.map(_.name.toString).mkString(, ), view.editAction, view.removeAction ) }) }) openOr Text(You're not logged in) and, I get a null value exception when I try to remove a user in the list. Simply using val view = new ModelView(new User, this), doesn't work either, although I don't get an exception. Now, where should I be calling load in all of this? Glenn... On Aug 3, 6:22 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Your snippet should extend ModelSnippet (which extends StatefulSnippet). Then write: val view = new ModelView(new User, this) {} Calling load on another ModelView that references the snippet will load its entity into that view val. It has a number of methods of possible interest, like save which checks validity. Also see Util. Are you seeing the scaladocs? - glenngl...@exmbly.com wrote: Just to add to what I just wrote, I don't see how your ModelView can be applied to User, which already extends a class, MegaProtoUser. Maybe I'm not comprehending this correctly. Glenn... On Aug 3, 3:48 pm, glenn gl...@exmbly.com wrote: Naftoli, Liked your OneToMany article, but not sure how the new ModelView and ModelSnippet code can be applied to ManyToMany. Can you provide a sample? Glenn... On Aug 2, 1:21 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I put an article on the wiki about OneToMany --http://wiki.github.com/dpp/liftweb/how-to-work-with-one-to-many-relat... . On Sun, Aug 2, 2009 at 11:20 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: Glad to hear. Also see mapper.view.ItemsList (anyone have a better name?), which is used by TableEditor. It's a similar idea without relationships. Should MappedOne/ManyToMany be based on ItemsList? Also should I take Mapped out of those names? After all, they're not MappedFields and they don't correspond to a table column. - Magnus Alvestadmagnus.alves...@gmail.com wrote: This work that you've done in Mapper fits in very well with something I've been planning to do. In a Java project some time ago we implemented a 'change engine'. We were loading big pension agreements, manipulating them in a web interface and finally saving them back to the database. While the user was working on the agreement, we generated a list of changes, containing enough information to replay or unroll the change. We could use this to implement undo and some semi-intelligent merging when two users were trying to commit changes to the same agreement. We also let the user review his changes before saving, and we indicated changed fields visually. We were even thinking of implementing some kind of macro or replay functionality, but never got that far. I've been trying to implement something similar as a lift component, but with the old relationship handling it wasn't practical. With your changes it should be. Thanks! -Magnus On Jul 27, 9:57 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed some code last night, which can help building mapper-based view snippets, with G-d's help. It includes the following classes: (1-2) net.liftweb.mapper.OneToMany, ManyToMany: Gives a more object-oriented approach to managing related
[Lift] Re: New features
Naftoli, I fixed my code per your comments and now I can edit and remove users from a list, as long as I populate the list with ModelView instances, as you said. As for the docs, this step was not clear to me at all. I just assumed that the list was just populated with User entities and the view in the ModelSnippet was instantiated with the selected User on each request. It sounds like your plate is pretty full, so I won't expect much, but sometime soon, could you provide an example, or improved docs, for using TableEditor and its related ItemsList trait. Thanks for all. Glenn... On Aug 5, 9:18 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Correction: ModelSnippet.load takes the actual Mapper instance, not the ModelView wrapper. - Naftoli Gugenheimnaftoli...@gmail.com wrote: To answer your immediate question, the listing should not refer to the snippet's view but new ModelView instances for each entity. Then editAction is shorthand for the snippet's link method with a callback to call load on the ModelView. To set the snippet's view's entity, either call load on the snippet with the other ModelView, or call load on the other ModelView (or just set its entity directly). As far as documentation, please tell me what scaladocs need what clarification. Thanks. - glenngl...@exmbly.com wrote: Naftoli, Functional programming systems are notoriously difficult to document. The only way to really know what's going on is to meticulously trace through the source. But that requires time-consuming trial and error coding. So, without clear examples demonstrating exactly what you have in mind, I and others in the same boat, could spend days and still not get it right. For example, I tried this: var theUser:User = null val view = new ModelView(theUser, this) def list(ns: NodeSeq): NodeSeq = User.currentUser.map({user = User.findAll.flatMap({u = bind(user, chooseTemplate(user, entry, ns), firstname - Text(u.firstName.is), lastname - Text(u.lastName.is), email - Text(u.email.is), roles - u.roles.map(_.name.toString).mkString(, ), view.editAction, view.removeAction ) }) }) openOr Text(You're not logged in) and, I get a null value exception when I try to remove a user in the list. Simply using val view = new ModelView(new User, this), doesn't work either, although I don't get an exception. Now, where should I be calling load in all of this? Glenn... On Aug 3, 6:22 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Your snippet should extend ModelSnippet (which extends StatefulSnippet). Then write: val view = new ModelView(new User, this) {} Calling load on another ModelView that references the snippet will load its entity into that view val. It has a number of methods of possible interest, like save which checks validity. Also see Util. Are you seeing the scaladocs? - glenngl...@exmbly.com wrote: Just to add to what I just wrote, I don't see how your ModelView can be applied to User, which already extends a class, MegaProtoUser. Maybe I'm not comprehending this correctly. Glenn... On Aug 3, 3:48 pm, glenn gl...@exmbly.com wrote: Naftoli, Liked your OneToMany article, but not sure how the new ModelView and ModelSnippet code can be applied to ManyToMany. Can you provide a sample? Glenn... On Aug 2, 1:21 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I put an article on the wiki about OneToMany --http://wiki.github.com/dpp/liftweb/how-to-work-with-one-to-many-relat... . On Sun, Aug 2, 2009 at 11:20 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: Glad to hear. Also see mapper.view.ItemsList (anyone have a better name?), which is used byTableEditor. It's a similar idea without relationships. Should MappedOne/ManyToMany be based on ItemsList? Also should I take Mapped out of those names? After all, they're not MappedFields and they don't correspond to a table column. - Magnus Alvestadmagnus.alves...@gmail.com wrote: This work that you've done in Mapper fits in very well with something I've been planning to do. In a Java project some time ago we implemented a 'change engine'. We were loading big pension agreements, manipulating them in a web interface and finally saving them back to the database. While the user was working on the agreement, we generated a list of changes, containing enough information to replay or unroll the change. We could use this to implement undo and some semi-intelligent merging when two users were trying to commit changes to the same
[Lift] Re: New features
I'll try. By the way, as per my correction, you can implement list the regular way without ModelView, and just use ModelSnippet's load function in your edit link or button, passing it the User instance. - glenngl...@exmbly.com wrote: Naftoli, I fixed my code per your comments and now I can edit and remove users from a list, as long as I populate the list with ModelView instances, as you said. As for the docs, this step was not clear to me at all. I just assumed that the list was just populated with User entities and the view in the ModelSnippet was instantiated with the selected User on each request. It sounds like your plate is pretty full, so I won't expect much, but sometime soon, could you provide an example, or improved docs, for using TableEditor and its related ItemsList trait. Thanks for all. Glenn... On Aug 5, 9:18 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Correction: ModelSnippet.load takes the actual Mapper instance, not the ModelView wrapper. - Naftoli Gugenheimnaftoli...@gmail.com wrote: To answer your immediate question, the listing should not refer to the snippet's view but new ModelView instances for each entity. Then editAction is shorthand for the snippet's link method with a callback to call load on the ModelView. To set the snippet's view's entity, either call load on the snippet with the other ModelView, or call load on the other ModelView (or just set its entity directly). As far as documentation, please tell me what scaladocs need what clarification. Thanks. - glenngl...@exmbly.com wrote: Naftoli, Functional programming systems are notoriously difficult to document. The only way to really know what's going on is to meticulously trace through the source. But that requires time-consuming trial and error coding. So, without clear examples demonstrating exactly what you have in mind, I and others in the same boat, could spend days and still not get it right. For example, I tried this: var theUser:User = null val view = new ModelView(theUser, this) def list(ns: NodeSeq): NodeSeq = User.currentUser.map({user = User.findAll.flatMap({u = bind(user, chooseTemplate(user, entry, ns), firstname - Text(u.firstName.is), lastname - Text(u.lastName.is), email - Text(u.email.is), roles - u.roles.map(_.name.toString).mkString(, ), view.editAction, view.removeAction ) }) }) openOr Text(You're not logged in) and, I get a null value exception when I try to remove a user in the list. Simply using val view = new ModelView(new User, this), doesn't work either, although I don't get an exception. Now, where should I be calling load in all of this? Glenn... On Aug 3, 6:22 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Your snippet should extend ModelSnippet (which extends StatefulSnippet). Then write: val view = new ModelView(new User, this) {} Calling load on another ModelView that references the snippet will load its entity into that view val. It has a number of methods of possible interest, like save which checks validity. Also see Util. Are you seeing the scaladocs? - glenngl...@exmbly.com wrote: Just to add to what I just wrote, I don't see how your ModelView can be applied to User, which already extends a class, MegaProtoUser. Maybe I'm not comprehending this correctly. Glenn... On Aug 3, 3:48 pm, glenn gl...@exmbly.com wrote: Naftoli, Liked your OneToMany article, but not sure how the new ModelView and ModelSnippet code can be applied to ManyToMany. Can you provide a sample? Glenn... On Aug 2, 1:21 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I put an article on the wiki about OneToMany --http://wiki.github.com/dpp/liftweb/how-to-work-with-one-to-many-relat... . On Sun, Aug 2, 2009 at 11:20 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: Glad to hear. Also see mapper.view.ItemsList (anyone have a better name?), which is used byTableEditor. It's a similar idea without relationships. Should MappedOne/ManyToMany be based on ItemsList? Also should I take Mapped out of those names? After all, they're not MappedFields and they don't correspond to a table column. - Magnus Alvestadmagnus.alves...@gmail.com wrote: This work that you've done in Mapper fits in very well with something I've been planning to do. In a Java project some time ago we implemented a 'change engine'. We were loading big pension agreements, manipulating them in a web interface and finally saving them back to the database. While the user was
[Lift] Re: New features
Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli Gugenheim naftoli...@gmail.com wrote: I'll try. By the way, as per my correction, you can implement list the regular way without ModelView, and just use ModelSnippet's load function in your edit link or button, passing it the User instance. - glenngl...@exmbly.com wrote: Naftoli, I fixed my code per your comments and now I can edit and remove users from a list, as long as I populate the list with ModelView instances, as you said. As for the docs, this step was not clear to me at all. I just assumed that the list was just populated with User entities and the view in the ModelSnippet was instantiated with the selected User on each request. It sounds like your plate is pretty full, so I won't expect much, but sometime soon, could you provide an example, or improved docs, for using TableEditor and its related ItemsList trait. Thanks for all. Glenn... On Aug 5, 9:18 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Correction: ModelSnippet.load takes the actual Mapper instance, not the ModelView wrapper. - Naftoli Gugenheimnaftoli...@gmail.com wrote: To answer your immediate question, the listing should not refer to the snippet's view but new ModelView instances for each entity. Then editAction is shorthand for the snippet's link method with a callback to call load on the ModelView. To set the snippet's view's entity, either call load on the snippet with the other ModelView, or call load on the other ModelView (or just set its entity directly). As far as documentation, please tell me what scaladocs need what clarification. Thanks. - glenngl...@exmbly.com wrote: Naftoli, Functional programming systems are notoriously difficult to document. The only way to really know what's going on is to meticulously trace through the source. But that requires time-consuming trial and error coding. So, without clear examples demonstrating exactly what you have in mind, I and others in the same boat, could spend days and still not get it right. For example, I tried this: var theUser:User = null val view = new ModelView(theUser, this) def list(ns: NodeSeq): NodeSeq = User.currentUser.map({user = User.findAll.flatMap({u = bind(user, chooseTemplate(user, entry, ns), firstname - Text(u.firstName.is), lastname - Text(u.lastName.is), email - Text(u.email.is), roles - u.roles.map(_.name.toString).mkString(, ), view.editAction, view.removeAction
[Lift] Re: New features
First of all, let me tell you what the error means. It means that there is a relevant row in the join table that doesn't have a corresponding element in the other table. Specifically, calling joinRecord.childMappedForeignKey.obj, so to speak, returns Empty. The question is how it got to this inconsistent state. When you add a Role to a User, MappedManyToMany creates a UserRole for it. For some reason though there is a UserRole without a Role or User. Can you send me a self-contained project? Also is it high priority? - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli Gugenheim naftoli...@gmail.com wrote: I'll try. By the way, as per my correction, you can implement list the regular way without ModelView, and just use ModelSnippet's load function in your edit link or button, passing it the User instance. - glenngl...@exmbly.com wrote: Naftoli, I fixed my code per your comments and now I can edit and remove users from a list, as long as I populate the list with ModelView instances, as you said. As for the docs, this step was not clear to me at all. I just assumed that the list was just populated with User entities and the view in the ModelSnippet was instantiated with the selected User on each request. It sounds like your plate is pretty full, so I won't expect much, but sometime soon, could you provide an example, or improved docs, for using TableEditor and its related ItemsList trait. Thanks for all. Glenn... On Aug 5, 9:18 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Correction: ModelSnippet.load takes the actual Mapper instance, not the ModelView wrapper. - Naftoli Gugenheimnaftoli...@gmail.com wrote: To answer your immediate question, the listing should not refer to the snippet's view but new ModelView instances for each entity. Then editAction is shorthand for the snippet's link method with a callback to call load on the ModelView. To set the snippet's view's entity, either call load on the snippet with the other ModelView, or call load on the other ModelView (or just set its entity directly). As far as documentation, please tell me what scaladocs need what clarification. Thanks. - glenngl...@exmbly.com wrote: Naftoli, Functional programming systems are notoriously difficult to document. The only way to really know what's going on is to meticulously trace through the source. But that requires time-consuming trial and error coding. So, without clear examples demonstrating exactly what you have in mind, I and others in the same boat, could spend days
[Lift] Re: New features
Oh, I think I know what the problem is. I think I should classify it as a bug. Since you're adding a Role that isn't saved yet, and ManyToMany tracks the children via the join table, it can't access the child. As a workaround save the Role before adding it, although the need to do so is against the idea of ManyToMany and OneToMany. I will see what I can do, G-d willing. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli Gugenheim naftoli...@gmail.com wrote: I'll try. By the way, as per my correction, you can implement list the regular way without ModelView, and just use ModelSnippet's load function in your edit link or button, passing it the User instance. - glenngl...@exmbly.com wrote: Naftoli, I fixed my code per your comments and now I can edit and remove users from a list, as long as I populate the list with ModelView instances, as you said. As for the docs, this step was not clear to me at all. I just assumed that the list was just populated with User entities and the view in the ModelSnippet was instantiated with the selected User on each request. It sounds like your plate is pretty full, so I won't expect much, but sometime soon, could you provide an example, or improved docs, for using TableEditor and its related ItemsList trait. Thanks for all. Glenn... On Aug 5, 9:18 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Correction: ModelSnippet.load takes the actual Mapper instance, not the ModelView wrapper. - Naftoli Gugenheimnaftoli...@gmail.com wrote: To answer your immediate question, the listing should not refer to the snippet's view but new ModelView instances for each entity. Then editAction is shorthand for the snippet's link method with a callback to call load on the ModelView. To set the snippet's view's entity, either call load on the snippet with the other ModelView, or call load on the other ModelView (or just set its entity directly). As far as documentation, please tell me what scaladocs need what clarification. Thanks. - glenngl...@exmbly.com wrote: Naftoli, Functional programming systems are notoriously difficult to document. The only way to really know what's going on is to meticulously trace through the source. But that requires time-consuming trial and error coding. So, without clear examples demonstrating exactly what you have in mind, I and others in the same boat, could spend days and still not get it right. For example, I tried this: var theUser:User = null val view = new ModelView(theUser, this) def list(ns:
[Lift] Re: New features
Naftoli, While your working on this issue, there seems to be another. Here's what's happening: If I make a coding mistake, and code User as follows: class User extends MegaProtoUser[User] with ManyToMany[Long,Role]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } instead of class User extends MegaProtoUser[User] with ManyToMany[LongUser]{ ... I don't get a compiler error (I'm using Eclipse with the Scala plugin). Instead, I get a stack overflow error and my IDE crashes. Glenn... On Aug 5, 3:39 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Oh, I think I know what the problem is. I think I should classify it as a bug. Since you're adding a Role that isn't saved yet, and ManyToMany tracks the children via the join table, it can't access the child. As a workaround save the Role before adding it, although the need to do so is against the idea of ManyToMany and OneToMany. I will see what I can do, G-d willing. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli Gugenheim naftoli...@gmail.com wrote: I'll try. By the way, as per my correction, you can implement list the regular way without ModelView, and just use ModelSnippet's load function in your edit link or button, passing it the User instance. - glenngl...@exmbly.com wrote: Naftoli, I fixed my code per your comments and now I can edit and remove users from a list, as long as I populate the list with ModelView instances, as you said. As for the docs, this step was not clear to me at all. I just assumed that the list was just populated with User entities and the view in the ModelSnippet was instantiated with the selected User on each request. It sounds like your plate is pretty full, so I won't expect much, but sometime soon, could you provide an example, or improved docs, for using TableEditor and its related ItemsList trait. Thanks for all. Glenn... On Aug 5, 9:18 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Correction: ModelSnippet.load takes the actual Mapper instance, not the ModelView wrapper. - Naftoli Gugenheimnaftoli...@gmail.com wrote: To answer your immediate question, the listing should not refer to the snippet's view but new ModelView instances for each entity. Then editAction is shorthand for the snippet's link method with a callback to call load on the ModelView. To set the snippet's view's entity, either call load on the snippet with the other ModelView, or
[Lift] Re: New features
Building causes a stack overflow? So the question is, is it the resident compiler or plain scalac also crashes? Or just the presentation compiler? What do you see in the error log view or file? I get compiler crashes very often when doing fancy mapper type related tricks. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli Gugenheim naftoli...@gmail.com wrote: I'll try. By the way, as per my correction, you can implement list the regular way without ModelView, and just use ModelSnippet's load function in your edit link or button, passing it the User instance. - glenngl...@exmbly.com wrote: Naftoli, I fixed my code per your comments and now I can edit and remove users from a list, as long as I populate the list with ModelView instances, as you said. As for the docs, this step was not clear to me at all. I just assumed that the list was just populated with User entities and the view in the ModelSnippet was instantiated with the selected User on each request. It sounds like your plate is pretty full, so I won't expect much, but sometime soon, could you provide an example, or improved docs, for using TableEditor and its related ItemsList trait. Thanks for all. Glenn... On Aug 5, 9:18 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Correction: ModelSnippet.load takes the actual Mapper instance, not the ModelView wrapper. - Naftoli Gugenheimnaftoli...@gmail.com wrote: To answer your immediate question, the listing should not refer to the snippet's view but new ModelView instances for each entity. Then editAction is shorthand for the snippet's link method with a callback to call load on the ModelView. To set the snippet's view's entity, either call load on the snippet with the other ModelView, or call load on the other ModelView (or just set its entity directly). As far as documentation, please tell me what scaladocs need what clarification. Thanks. - glenngl...@exmbly.com wrote: Naftoli, Functional programming systems are notoriously difficult to document. The only way to really know what's going on is to meticulously trace through the source. But that requires time-consuming trial and error coding. So, without clear examples demonstrating exactly what you have in mind, I and others in the same boat, could spend days and still not get it right. For example, I tried this: var theUser:User = null val view = new ModelView(theUser, this) def list(ns: NodeSeq): NodeSeq = User.currentUser.map({user = User.findAll.flatMap({u =
[Lift] Re: New features
To answer your immediate question, the listing should not refer to the snippet's view but new ModelView instances for each entity. Then editAction is shorthand for the snippet's link method with a callback to call load on the ModelView. To set the snippet's view's entity, either call load on the snippet with the other ModelView, or call load on the other ModelView (or just set its entity directly). As far as documentation, please tell me what scaladocs need what clarification. Thanks. - glenngl...@exmbly.com wrote: Naftoli, Functional programming systems are notoriously difficult to document. The only way to really know what's going on is to meticulously trace through the source. But that requires time-consuming trial and error coding. So, without clear examples demonstrating exactly what you have in mind, I and others in the same boat, could spend days and still not get it right. For example, I tried this: var theUser:User = null val view = new ModelView(theUser, this) def list(ns: NodeSeq): NodeSeq = User.currentUser.map({user = User.findAll.flatMap({u = bind(user, chooseTemplate(user, entry, ns), firstname - Text(u.firstName.is), lastname - Text(u.lastName.is), email - Text(u.email.is), roles - u.roles.map(_.name.toString).mkString(, ), view.editAction, view.removeAction ) }) }) openOr Text(You're not logged in) and, I get a null value exception when I try to remove a user in the list. Simply using val view = new ModelView(new User, this), doesn't work either, although I don't get an exception. Now, where should I be calling load in all of this? Glenn... On Aug 3, 6:22 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Your snippet should extend ModelSnippet (which extends StatefulSnippet). Then write: val view = new ModelView(new User, this) {} Calling load on another ModelView that references the snippet will load its entity into that view val. It has a number of methods of possible interest, like save which checks validity. Also see Util. Are you seeing the scaladocs? - glenngl...@exmbly.com wrote: Just to add to what I just wrote, I don't see how your ModelView can be applied to User, which already extends a class, MegaProtoUser. Maybe I'm not comprehending this correctly. Glenn... On Aug 3, 3:48 pm, glenn gl...@exmbly.com wrote: Naftoli, Liked your OneToMany article, but not sure how the new ModelView and ModelSnippet code can be applied to ManyToMany. Can you provide a sample? Glenn... On Aug 2, 1:21 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I put an article on the wiki about OneToMany --http://wiki.github.com/dpp/liftweb/how-to-work-with-one-to-many-relat... . On Sun, Aug 2, 2009 at 11:20 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: Glad to hear. Also see mapper.view.ItemsList (anyone have a better name?), which is used by TableEditor. It's a similar idea without relationships. Should MappedOne/ManyToMany be based on ItemsList? Also should I take Mapped out of those names? After all, they're not MappedFields and they don't correspond to a table column. - Magnus Alvestadmagnus.alves...@gmail.com wrote: This work that you've done in Mapper fits in very well with something I've been planning to do. In a Java project some time ago we implemented a 'change engine'. We were loading big pension agreements, manipulating them in a web interface and finally saving them back to the database. While the user was working on the agreement, we generated a list of changes, containing enough information to replay or unroll the change. We could use this to implement undo and some semi-intelligent merging when two users were trying to commit changes to the same agreement. We also let the user review his changes before saving, and we indicated changed fields visually. We were even thinking of implementing some kind of macro or replay functionality, but never got that far. I've been trying to implement something similar as a lift component, but with the old relationship handling it wasn't practical. With your changes it should be. Thanks! -Magnus On Jul 27, 9:57 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed some code last night, which can help building mapper-based view snippets, with G-d's help. It includes the following classes: (1-2) net.liftweb.mapper.OneToMany, ManyToMany: Gives a more object-oriented approach to managing related entites. You can manage the many side of a 1-n and n-n as a mutable collection of children, and the parent of a child can be set directly, instead of via its id. And the
[Lift] Re: New features
Naftoli, Liked your OneToMany article, but not sure how the new ModelView and ModelSnippet code can be applied to ManyToMany. Can you provide a sample? Glenn... On Aug 2, 1:21 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I put an article on the wiki about OneToMany --http://wiki.github.com/dpp/liftweb/how-to-work-with-one-to-many-relat... . On Sun, Aug 2, 2009 at 11:20 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: Glad to hear. Also see mapper.view.ItemsList (anyone have a better name?), which is used by TableEditor. It's a similar idea without relationships. Should MappedOne/ManyToMany be based on ItemsList? Also should I take Mapped out of those names? After all, they're not MappedFields and they don't correspond to a table column. - Magnus Alvestadmagnus.alves...@gmail.com wrote: This work that you've done in Mapper fits in very well with something I've been planning to do. In a Java project some time ago we implemented a 'change engine'. We were loading big pension agreements, manipulating them in a web interface and finally saving them back to the database. While the user was working on the agreement, we generated a list of changes, containing enough information to replay or unroll the change. We could use this to implement undo and some semi-intelligent merging when two users were trying to commit changes to the same agreement. We also let the user review his changes before saving, and we indicated changed fields visually. We were even thinking of implementing some kind of macro or replay functionality, but never got that far. I've been trying to implement something similar as a lift component, but with the old relationship handling it wasn't practical. With your changes it should be. Thanks! -Magnus On Jul 27, 9:57 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed some code last night, which can help building mapper-based view snippets, with G-d's help. It includes the following classes: (1-2) net.liftweb.mapper.OneToMany, ManyToMany: Gives a more object-oriented approach to managing related entites. You can manage the many side of a 1-n and n-n as a mutable collection of children, and the parent of a child can be set directly, instead of via its id. And the children are not saved to the database when you add them until you call save on it or its parent, nor deleted when you remove tem until you call delete_!, which is very helpful when you need to keep track of adds/removes through multiple requests. For example, if you are displaying a list and you can click delete, but it shouldn't be permanently deleted until you click save. There is a new package, ...mapper.view, which contains a number of utilities for mapper-based views: (3-4) ModelView and ModelSnippet provide a number of building blocks for views that are too complex to CRUDify. Inherit ModelSnippet (which extends StatefulSnippet) and wrap your entities in ModelView (view is used in the sense of a wrapper). (5) Util provides some more building blocks that just be imported, without needing a ModelSnippet context. (6-7) Paginator makes it easy to create paginated, user sortable listings. You can use PaginatedSnippet instead of ModelSnippet to help. (8-10) ItemsList lets you manage a list of entities with pending additions and deletions. It's used by TableEditor, which is a very easy to use and customizable snippet to edit tables directly. It's useful for editing short lists, e.g., a lookup table like cities. Don't forget to register the table in Boot. (11) Then there's the experimental FormProcessor, if you need your form to be processed in one block instead of separate closures, e.g., to surround with try. (12) Also experimental is sitemap.XmlMenu which lets you write menus in xml. (13) I may add CaseEnum, which lets you write case classes that automatically double as an Enumeration. Questions, comments, suggestions, and constructive criticism are more than welcome! Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: New features
Just to add to what I just wrote, I don't see how your ModelView can be applied to User, which already extends a class, MegaProtoUser. Maybe I'm not comprehending this correctly. Glenn... On Aug 3, 3:48 pm, glenn gl...@exmbly.com wrote: Naftoli, Liked your OneToMany article, but not sure how the new ModelView and ModelSnippet code can be applied to ManyToMany. Can you provide a sample? Glenn... On Aug 2, 1:21 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I put an article on the wiki about OneToMany --http://wiki.github.com/dpp/liftweb/how-to-work-with-one-to-many-relat... . On Sun, Aug 2, 2009 at 11:20 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: Glad to hear. Also see mapper.view.ItemsList (anyone have a better name?), which is used by TableEditor. It's a similar idea without relationships. Should MappedOne/ManyToMany be based on ItemsList? Also should I take Mapped out of those names? After all, they're not MappedFields and they don't correspond to a table column. - Magnus Alvestadmagnus.alves...@gmail.com wrote: This work that you've done in Mapper fits in very well with something I've been planning to do. In a Java project some time ago we implemented a 'change engine'. We were loading big pension agreements, manipulating them in a web interface and finally saving them back to the database. While the user was working on the agreement, we generated a list of changes, containing enough information to replay or unroll the change. We could use this to implement undo and some semi-intelligent merging when two users were trying to commit changes to the same agreement. We also let the user review his changes before saving, and we indicated changed fields visually. We were even thinking of implementing some kind of macro or replay functionality, but never got that far. I've been trying to implement something similar as a lift component, but with the old relationship handling it wasn't practical. With your changes it should be. Thanks! -Magnus On Jul 27, 9:57 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed some code last night, which can help building mapper-based view snippets, with G-d's help. It includes the following classes: (1-2) net.liftweb.mapper.OneToMany, ManyToMany: Gives a more object-oriented approach to managing related entites. You can manage the many side of a 1-n and n-n as a mutable collection of children, and the parent of a child can be set directly, instead of via its id. And the children are not saved to the database when you add them until you call save on it or its parent, nor deleted when you remove tem until you call delete_!, which is very helpful when you need to keep track of adds/removes through multiple requests. For example, if you are displaying a list and you can click delete, but it shouldn't be permanently deleted until you click save. There is a new package, ...mapper.view, which contains a number of utilities for mapper-based views: (3-4) ModelView and ModelSnippet provide a number of building blocks for views that are too complex to CRUDify. Inherit ModelSnippet (which extends StatefulSnippet) and wrap your entities in ModelView (view is used in the sense of a wrapper). (5) Util provides some more building blocks that just be imported, without needing a ModelSnippet context. (6-7) Paginator makes it easy to create paginated, user sortable listings. You can use PaginatedSnippet instead of ModelSnippet to help. (8-10) ItemsList lets you manage a list of entities with pending additions and deletions. It's used by TableEditor, which is a very easy to use and customizable snippet to edit tables directly. It's useful for editing short lists, e.g., a lookup table like cities. Don't forget to register the table in Boot. (11) Then there's the experimental FormProcessor, if you need your form to be processed in one block instead of separate closures, e.g., to surround with try. (12) Also experimental is sitemap.XmlMenu which lets you write menus in xml. (13) I may add CaseEnum, which lets you write case classes that automatically double as an Enumeration. Questions, comments, suggestions, and constructive criticism are more than welcome! Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: New features
Your snippet should extend ModelSnippet (which extends StatefulSnippet). Then write: val view = new ModelView(new User, this) {} Calling load on another ModelView that references the snippet will load its entity into that view val. It has a number of methods of possible interest, like save which checks validity. Also see Util. Are you seeing the scaladocs? - glenngl...@exmbly.com wrote: Just to add to what I just wrote, I don't see how your ModelView can be applied to User, which already extends a class, MegaProtoUser. Maybe I'm not comprehending this correctly. Glenn... On Aug 3, 3:48 pm, glenn gl...@exmbly.com wrote: Naftoli, Liked your OneToMany article, but not sure how the new ModelView and ModelSnippet code can be applied to ManyToMany. Can you provide a sample? Glenn... On Aug 2, 1:21 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I put an article on the wiki about OneToMany --http://wiki.github.com/dpp/liftweb/how-to-work-with-one-to-many-relat... . On Sun, Aug 2, 2009 at 11:20 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: Glad to hear. Also see mapper.view.ItemsList (anyone have a better name?), which is used by TableEditor. It's a similar idea without relationships. Should MappedOne/ManyToMany be based on ItemsList? Also should I take Mapped out of those names? After all, they're not MappedFields and they don't correspond to a table column. - Magnus Alvestadmagnus.alves...@gmail.com wrote: This work that you've done in Mapper fits in very well with something I've been planning to do. In a Java project some time ago we implemented a 'change engine'. We were loading big pension agreements, manipulating them in a web interface and finally saving them back to the database. While the user was working on the agreement, we generated a list of changes, containing enough information to replay or unroll the change. We could use this to implement undo and some semi-intelligent merging when two users were trying to commit changes to the same agreement. We also let the user review his changes before saving, and we indicated changed fields visually. We were even thinking of implementing some kind of macro or replay functionality, but never got that far. I've been trying to implement something similar as a lift component, but with the old relationship handling it wasn't practical. With your changes it should be. Thanks! -Magnus On Jul 27, 9:57 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed some code last night, which can help building mapper-based view snippets, with G-d's help. It includes the following classes: (1-2) net.liftweb.mapper.OneToMany, ManyToMany: Gives a more object-oriented approach to managing related entites. You can manage the many side of a 1-n and n-n as a mutable collection of children, and the parent of a child can be set directly, instead of via its id. And the children are not saved to the database when you add them until you call save on it or its parent, nor deleted when you remove tem until you call delete_!, which is very helpful when you need to keep track of adds/removes through multiple requests. For example, if you are displaying a list and you can click delete, but it shouldn't be permanently deleted until you click save. There is a new package, ...mapper.view, which contains a number of utilities for mapper-based views: (3-4) ModelView and ModelSnippet provide a number of building blocks for views that are too complex to CRUDify. Inherit ModelSnippet (which extends StatefulSnippet) and wrap your entities in ModelView (view is used in the sense of a wrapper). (5) Util provides some more building blocks that just be imported, without needing a ModelSnippet context. (6-7) Paginator makes it easy to create paginated, user sortable listings. You can use PaginatedSnippet instead of ModelSnippet to help. (8-10) ItemsList lets you manage a list of entities with pending additions and deletions. It's used by TableEditor, which is a very easy to use and customizable snippet to edit tables directly. It's useful for editing short lists, e.g., a lookup table like cities. Don't forget to register the table in Boot. (11) Then there's the experimental FormProcessor, if you need your form to be processed in one block instead of separate closures, e.g., to surround with try. (12) Also experimental is sitemap.XmlMenu which lets you write menus in xml. (13) I may add CaseEnum, which lets you write case classes that automatically double as an Enumeration. Questions, comments, suggestions, and constructive criticism are more than welcome! Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the
[Lift] Re: New features
Naftoli, I set up my mapper to use your new ManyToMany trait, but I'm not sure how exactly to use it in a snippet or view. Here's what I have so far, a User, Role and UserRole for my model classes: class Role extends LongKeyedMapper[Role] with IdPK { def getSingleton = Role object name extends MappedPoliteString(this, 50) { override def setFilter = notNull _ :: trim _ :: super.setFilter } } class UserRole extends LongKeyedMapper[UserRole] with IdPK { def getSingleton = UserRole object role extends MappedLongForeignKey(this, Role){ override def dbIndexed_? = true } object user extends MappedLongForeignKey(this,User) { override def dbIndexed_? = true } } class User extends MegaProtoUser[User] with ManyToMany[UserRole, Role] { def getSingleton = User // what's the meta server // define an additional field for a personal essay object textArea extends MappedTextarea(this, 2048) { override def textareaRows = 10 override def textareaCols = 50 override def displayName = Personal Essay } object role extends MappedManyToMany(UserRole, this, Role) } and their corresponding singleton objects. In the past, without the ManyToMany trait, I would do this in User object override def editXhtml(user: User) = { (form method=post action={S.uri} tabletrtd colspan=2{S.??(edit)}/td/tr {localForm(user, true)} trtdRoles/tdtduser:roles//td/tr trtdnbsp;/tdtduser:submit//td/tr trtda href={changePasswordPath.mkString(/, /, )} {S.??(change.password)}/a/td/tr /table /form) } and bind this with the following to show the roles for a particular user as a comma delimited string. def innerEdit = User.isa_?(admin) match { case true = bind(user, editXhtml(theUser), roles - text(roles, doRolesAndSubmit), submit - SHtml.submit(S.??(edit), testEdit _)) case false = bind(user, editXhtml(theUser), roles - theUser.showRoles, submit - SHtml.submit(S.??(edit), testEdit _)) } here roles is defined as var roles = theUser.roles.map(_.name.is).mkString(, ) Do you have an example of how to achieve something similar with your new ManyToMany and MappedManyToMany code? Appreciate any help you can give me. Thanks, Glenn... On Jul 28, 3:05 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Did you update your source jar? Try deleting it from your repository just to be sure, then mvn dependency:sources etc. Either way you can access the source on github. - glenngl...@exmbly.com wrote: Naftoli, The ManyToMany class is in the new lift-mapper jar, but the source is not available in 1.1-SNAPSHOT-sources. Could you provide? Thanks, Glenn... On Jul 27, 3:50 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed it last night, so I think it should be there. To use many-to-many, simply mix ManyToMany to your mapper, then create a MappedManyToMany field like any other field. See the scaladocs for specifics. Then in your view you can use the field like a collection, e.g., remove an element with -=, and save the mapper to apply the changes. - glenngl...@exmbly.com wrote: Sounds great. I've been using hacks such as adding code like this to my mapper classes just to create a Many-to-Many relationship between say, tag and content tables (using an intermediary ContentTag table). Similarly, I've done User/Roles relationships. private object _dbTags extends HasManyThrough(this, Tag, ContentTag, ContentTag.content, ContentTag.tag) private[model] var _tags : List[Tag] = _ private val locker = new Object def tags : List[Tag] = locker.synchronized { if(_tags eq null){ _tags = _dbTags() } _tags } def tags(newTags:String) = locker.synchronized { _tags = newTags.roboSplit(,).map(Tag.byName(_)) this } def tags(newTags:List[Tag]) = locker.synchronized { _tags = newTags this } def tagsToo:List[Tag] = ContentTag.findAll(By(ContentTag.content, this.id)).map(_.tag.obj.open_!) def showTags = Text(tags.map(_.name.is).mkString(, )) But, then I have to add code like this to the meta-mapper objects: def addTags(entry: Content) { if(entry._tags ne null){ entry._tags.foreach(ContentTag.join(_, entry)) } } def delTags(entry:Content) = ContentTag.findAll(By(ContentTag.content, entry)).foreach (_.delete_!) It's not very pretty. Nor easy to duplicate. I hope your new code is considerably less messy. Is it in the repo-snapshot repository yet. On Jul 27, 12:57 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed some code last night, which can help building mapper-based view snippets, with G-d's help. It includes the
[Lift] Re: New features
I didn't yet look at your code too closely, but the idea is that the field that represents the relationship implements Buffer, so you can add, remove, and iterate its elements, which are the other side of the relationship. These changes are remembered until you call save, when they are acted on. - glenngl...@exmbly.com wrote: Naftoli, I set up my mapper to use your new ManyToMany trait, but I'm not sure how exactly to use it in a snippet or view. Here's what I have so far, a User, Role and UserRole for my model classes: class Role extends LongKeyedMapper[Role] with IdPK { def getSingleton = Role object name extends MappedPoliteString(this, 50) { override def setFilter = notNull _ :: trim _ :: super.setFilter } } class UserRole extends LongKeyedMapper[UserRole] with IdPK { def getSingleton = UserRole object role extends MappedLongForeignKey(this, Role){ override def dbIndexed_? = true } object user extends MappedLongForeignKey(this,User) { override def dbIndexed_? = true } } class User extends MegaProtoUser[User] with ManyToMany[UserRole, Role] { def getSingleton = User // what's the meta server // define an additional field for a personal essay object textArea extends MappedTextarea(this, 2048) { override def textareaRows = 10 override def textareaCols = 50 override def displayName = Personal Essay } object role extends MappedManyToMany(UserRole, this, Role) } and their corresponding singleton objects. In the past, without the ManyToMany trait, I would do this in User object override def editXhtml(user: User) = { (form method=post action={S.uri} tabletrtd colspan=2{S.??(edit)}/td/tr {localForm(user, true)} trtdRoles/tdtduser:roles//td/tr trtdnbsp;/tdtduser:submit//td/tr trtda href={changePasswordPath.mkString(/, /, )} {S.??(change.password)}/a/td/tr /table /form) } and bind this with the following to show the roles for a particular user as a comma delimited string. def innerEdit = User.isa_?(admin) match { case true = bind(user, editXhtml(theUser), roles - text(roles, doRolesAndSubmit), submit - SHtml.submit(S.??(edit), testEdit _)) case false = bind(user, editXhtml(theUser), roles - theUser.showRoles, submit - SHtml.submit(S.??(edit), testEdit _)) } here roles is defined as var roles = theUser.roles.map(_.name.is).mkString(, ) Do you have an example of how to achieve something similar with your new ManyToMany and MappedManyToMany code? Appreciate any help you can give me. Thanks, Glenn... On Jul 28, 3:05 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Did you update your source jar? Try deleting it from your repository just to be sure, then mvn dependency:sources etc. Either way you can access the source on github. - glenngl...@exmbly.com wrote: Naftoli, The ManyToMany class is in the new lift-mapper jar, but the source is not available in 1.1-SNAPSHOT-sources. Could you provide? Thanks, Glenn... On Jul 27, 3:50 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed it last night, so I think it should be there. To use many-to-many, simply mix ManyToMany to your mapper, then create a MappedManyToMany field like any other field. See the scaladocs for specifics. Then in your view you can use the field like a collection, e.g., remove an element with -=, and save the mapper to apply the changes. - glenngl...@exmbly.com wrote: Sounds great. I've been using hacks such as adding code like this to my mapper classes just to create a Many-to-Many relationship between say, tag and content tables (using an intermediary ContentTag table). Similarly, I've done User/Roles relationships. private object _dbTags extends HasManyThrough(this, Tag, ContentTag, ContentTag.content, ContentTag.tag) private[model] var _tags : List[Tag] = _ private val locker = new Object def tags : List[Tag] = locker.synchronized { if(_tags eq null){ _tags = _dbTags() } _tags } def tags(newTags:String) = locker.synchronized { _tags = newTags.roboSplit(,).map(Tag.byName(_)) this } def tags(newTags:List[Tag]) = locker.synchronized { _tags = newTags this } def tagsToo:List[Tag] = ContentTag.findAll(By(ContentTag.content, this.id)).map(_.tag.obj.open_!) def showTags = Text(tags.map(_.name.is).mkString(, )) But, then I have to add code like this to the meta-mapper objects: def addTags(entry: Content) { if(entry._tags ne null){ entry._tags.foreach(ContentTag.join(_, entry)) } } def delTags(entry:Content) = ContentTag.findAll(By(ContentTag.content,
[Lift] Re: New features
I should probably take Mapped out of the name, because it's not a MappedField. - glenngl...@exmbly.com wrote: Naftoli, I set up my mapper to use your new ManyToMany trait, but I'm not sure how exactly to use it in a snippet or view. Here's what I have so far, a User, Role and UserRole for my model classes: class Role extends LongKeyedMapper[Role] with IdPK { def getSingleton = Role object name extends MappedPoliteString(this, 50) { override def setFilter = notNull _ :: trim _ :: super.setFilter } } class UserRole extends LongKeyedMapper[UserRole] with IdPK { def getSingleton = UserRole object role extends MappedLongForeignKey(this, Role){ override def dbIndexed_? = true } object user extends MappedLongForeignKey(this,User) { override def dbIndexed_? = true } } class User extends MegaProtoUser[User] with ManyToMany[UserRole, Role] { def getSingleton = User // what's the meta server // define an additional field for a personal essay object textArea extends MappedTextarea(this, 2048) { override def textareaRows = 10 override def textareaCols = 50 override def displayName = Personal Essay } object role extends MappedManyToMany(UserRole, this, Role) } and their corresponding singleton objects. In the past, without the ManyToMany trait, I would do this in User object override def editXhtml(user: User) = { (form method=post action={S.uri} tabletrtd colspan=2{S.??(edit)}/td/tr {localForm(user, true)} trtdRoles/tdtduser:roles//td/tr trtdnbsp;/tdtduser:submit//td/tr trtda href={changePasswordPath.mkString(/, /, )} {S.??(change.password)}/a/td/tr /table /form) } and bind this with the following to show the roles for a particular user as a comma delimited string. def innerEdit = User.isa_?(admin) match { case true = bind(user, editXhtml(theUser), roles - text(roles, doRolesAndSubmit), submit - SHtml.submit(S.??(edit), testEdit _)) case false = bind(user, editXhtml(theUser), roles - theUser.showRoles, submit - SHtml.submit(S.??(edit), testEdit _)) } here roles is defined as var roles = theUser.roles.map(_.name.is).mkString(, ) Do you have an example of how to achieve something similar with your new ManyToMany and MappedManyToMany code? Appreciate any help you can give me. Thanks, Glenn... On Jul 28, 3:05 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Did you update your source jar? Try deleting it from your repository just to be sure, then mvn dependency:sources etc. Either way you can access the source on github. - glenngl...@exmbly.com wrote: Naftoli, The ManyToMany class is in the new lift-mapper jar, but the source is not available in 1.1-SNAPSHOT-sources. Could you provide? Thanks, Glenn... On Jul 27, 3:50 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed it last night, so I think it should be there. To use many-to-many, simply mix ManyToMany to your mapper, then create a MappedManyToMany field like any other field. See the scaladocs for specifics. Then in your view you can use the field like a collection, e.g., remove an element with -=, and save the mapper to apply the changes. - glenngl...@exmbly.com wrote: Sounds great. I've been using hacks such as adding code like this to my mapper classes just to create a Many-to-Many relationship between say, tag and content tables (using an intermediary ContentTag table). Similarly, I've done User/Roles relationships. private object _dbTags extends HasManyThrough(this, Tag, ContentTag, ContentTag.content, ContentTag.tag) private[model] var _tags : List[Tag] = _ private val locker = new Object def tags : List[Tag] = locker.synchronized { if(_tags eq null){ _tags = _dbTags() } _tags } def tags(newTags:String) = locker.synchronized { _tags = newTags.roboSplit(,).map(Tag.byName(_)) this } def tags(newTags:List[Tag]) = locker.synchronized { _tags = newTags this } def tagsToo:List[Tag] = ContentTag.findAll(By(ContentTag.content, this.id)).map(_.tag.obj.open_!) def showTags = Text(tags.map(_.name.is).mkString(, )) But, then I have to add code like this to the meta-mapper objects: def addTags(entry: Content) { if(entry._tags ne null){ entry._tags.foreach(ContentTag.join(_, entry)) } } def delTags(entry:Content) = ContentTag.findAll(By(ContentTag.content, entry)).foreach (_.delete_!) It's not very pretty. Nor easy to duplicate. I hope your new code is considerably less messy. Is it in the repo-snapshot repository yet. On Jul 27, 12:57 pm, Naftoli Gugenheim
[Lift] Re: New features
In the meantime, if there are any scaladoc comments that could be improved or clarified, please tell me! - marius d.marius.dan...@gmail.com wrote: Would you please add some examples on the wiki so that people can actually visualize how these things can be used? As far as XmlMenu goes why do we want to express menus as xml ? Br's, Marius On Jul 27, 10:57 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed some code last night, which can help building mapper-based view snippets, with G-d's help. It includes the following classes: (1-2) net.liftweb.mapper.OneToMany, ManyToMany: Gives a more object-oriented approach to managing related entites. You can manage the many side of a 1-n and n-n as a mutable collection of children, and the parent of a child can be set directly, instead of via its id. And the children are not saved to the database when you add them until you call save on it or its parent, nor deleted when you remove tem until you call delete_!, which is very helpful when you need to keep track of adds/removes through multiple requests. For example, if you are displaying a list and you can click delete, but it shouldn't be permanently deleted until you click save. There is a new package, ...mapper.view, which contains a number of utilities for mapper-based views: (3-4) ModelView and ModelSnippet provide a number of building blocks for views that are too complex to CRUDify. Inherit ModelSnippet (which extends StatefulSnippet) and wrap your entities in ModelView (view is used in the sense of a wrapper). (5) Util provides some more building blocks that just be imported, without needing a ModelSnippet context. (6-7) Paginator makes it easy to create paginated, user sortable listings. You can use PaginatedSnippet instead of ModelSnippet to help. (8-10) ItemsList lets you manage a list of entities with pending additions and deletions. It's used by TableEditor, which is a very easy to use and customizable snippet to edit tables directly. It's useful for editing short lists, e.g., a lookup table like cities. Don't forget to register the table in Boot. (11) Then there's the experimental FormProcessor, if you need your form to be processed in one block instead of separate closures, e.g., to surround with try. (12) Also experimental is sitemap.XmlMenu which lets you write menus in xml. (13) I may add CaseEnum, which lets you write case classes that automatically double as an Enumeration. Questions, comments, suggestions, and constructive criticism are more than welcome! Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: New features
Naftoli, The ManyToMany class is in the new lift-mapper jar, but the source is not available in 1.1-SNAPSHOT-sources. Could you provide? Thanks, Glenn... On Jul 27, 3:50 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed it last night, so I think it should be there. To use many-to-many, simply mix ManyToMany to your mapper, then create a MappedManyToMany field like any other field. See the scaladocs for specifics. Then in your view you can use the field like a collection, e.g., remove an element with -=, and save the mapper to apply the changes. - glenngl...@exmbly.com wrote: Sounds great. I've been using hacks such as adding code like this to my mapper classes just to create a Many-to-Many relationship between say, tag and content tables (using an intermediary ContentTag table). Similarly, I've done User/Roles relationships. private object _dbTags extends HasManyThrough(this, Tag, ContentTag, ContentTag.content, ContentTag.tag) private[model] var _tags : List[Tag] = _ private val locker = new Object def tags : List[Tag] = locker.synchronized { if(_tags eq null){ _tags = _dbTags() } _tags } def tags(newTags:String) = locker.synchronized { _tags = newTags.roboSplit(,).map(Tag.byName(_)) this } def tags(newTags:List[Tag]) = locker.synchronized { _tags = newTags this } def tagsToo:List[Tag] = ContentTag.findAll(By(ContentTag.content, this.id)).map(_.tag.obj.open_!) def showTags = Text(tags.map(_.name.is).mkString(, )) But, then I have to add code like this to the meta-mapper objects: def addTags(entry: Content) { if(entry._tags ne null){ entry._tags.foreach(ContentTag.join(_, entry)) } } def delTags(entry:Content) = ContentTag.findAll(By(ContentTag.content, entry)).foreach (_.delete_!) It's not very pretty. Nor easy to duplicate. I hope your new code is considerably less messy. Is it in the repo-snapshot repository yet. On Jul 27, 12:57 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed some code last night, which can help building mapper-based view snippets, with G-d's help. It includes the following classes: (1-2) net.liftweb.mapper.OneToMany, ManyToMany: Gives a more object-oriented approach to managing related entites. You can manage the many side of a 1-n and n-n as a mutable collection of children, and the parent of a child can be set directly, instead of via its id. And the children are not saved to the database when you add them until you call save on it or its parent, nor deleted when you remove tem until you call delete_!, which is very helpful when you need to keep track of adds/removes through multiple requests. For example, if you are displaying a list and you can click delete, but it shouldn't be permanently deleted until you click save. There is a new package, ...mapper.view, which contains a number of utilities for mapper-based views: (3-4) ModelView and ModelSnippet provide a number of building blocks for views that are too complex to CRUDify. Inherit ModelSnippet (which extends StatefulSnippet) and wrap your entities in ModelView (view is used in the sense of a wrapper). (5) Util provides some more building blocks that just be imported, without needing a ModelSnippet context. (6-7) Paginator makes it easy to create paginated, user sortable listings. You can use PaginatedSnippet instead of ModelSnippet to help. (8-10) ItemsList lets you manage a list of entities with pending additions and deletions. It's used by TableEditor, which is a very easy to use and customizable snippet to edit tables directly. It's useful for editing short lists, e.g., a lookup table like cities. Don't forget to register the table in Boot. (11) Then there's the experimental FormProcessor, if you need your form to be processed in one block instead of separate closures, e.g., to surround with try. (12) Also experimental is sitemap.XmlMenu which lets you write menus in xml. (13) I may add CaseEnum, which lets you write case classes that automatically double as an Enumeration. Questions, comments, suggestions, and constructive criticism are more than welcome! Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: New features
THis is all very good stuff. Thanks for contributing this excellent stuff to Lift! On Mon, Jul 27, 2009 at 12:57 PM, Naftoli Gugenheim naftoli...@gmail.comwrote: I committed some code last night, which can help building mapper-based view snippets, with G-d's help. It includes the following classes: (1-2) net.liftweb.mapper.OneToMany, ManyToMany: Gives a more object-oriented approach to managing related entites. You can manage the many side of a 1-n and n-n as a mutable collection of children, and the parent of a child can be set directly, instead of via its id. And the children are not saved to the database when you add them until you call save on it or its parent, nor deleted when you remove tem until you call delete_!, which is very helpful when you need to keep track of adds/removes through multiple requests. For example, if you are displaying a list and you can click delete, but it shouldn't be permanently deleted until you click save. There is a new package, ...mapper.view, which contains a number of utilities for mapper-based views: (3-4) ModelView and ModelSnippet provide a number of building blocks for views that are too complex to CRUDify. Inherit ModelSnippet (which extends StatefulSnippet) and wrap your entities in ModelView (view is used in the sense of a wrapper). (5) Util provides some more building blocks that just be imported, without needing a ModelSnippet context. (6-7) Paginator makes it easy to create paginated, user sortable listings. You can use PaginatedSnippet instead of ModelSnippet to help. (8-10) ItemsList lets you manage a list of entities with pending additions and deletions. It's used by TableEditor, which is a very easy to use and customizable snippet to edit tables directly. It's useful for editing short lists, e.g., a lookup table like cities. Don't forget to register the table in Boot. (11) Then there's the experimental FormProcessor, if you need your form to be processed in one block instead of separate closures, e.g., to surround with try. (12) Also experimental is sitemap.XmlMenu which lets you write menus in xml. (13) I may add CaseEnum, which lets you write case classes that automatically double as an Enumeration. Questions, comments, suggestions, and constructive criticism are more than welcome! Thanks. -- Lift, the simply functional web framework http://liftweb.net Beginning Scala http://www.apress.com/book/view/1430219890 Follow me: http://twitter.com/dpp Git some: http://github.com/dpp --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: New features
Would you please add some examples on the wiki so that people can actually visualize how these things can be used? As far as XmlMenu goes why do we want to express menus as xml ? Br's, Marius On Jul 27, 10:57 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed some code last night, which can help building mapper-based view snippets, with G-d's help. It includes the following classes: (1-2) net.liftweb.mapper.OneToMany, ManyToMany: Gives a more object-oriented approach to managing related entites. You can manage the many side of a 1-n and n-n as a mutable collection of children, and the parent of a child can be set directly, instead of via its id. And the children are not saved to the database when you add them until you call save on it or its parent, nor deleted when you remove tem until you call delete_!, which is very helpful when you need to keep track of adds/removes through multiple requests. For example, if you are displaying a list and you can click delete, but it shouldn't be permanently deleted until you click save. There is a new package, ...mapper.view, which contains a number of utilities for mapper-based views: (3-4) ModelView and ModelSnippet provide a number of building blocks for views that are too complex to CRUDify. Inherit ModelSnippet (which extends StatefulSnippet) and wrap your entities in ModelView (view is used in the sense of a wrapper). (5) Util provides some more building blocks that just be imported, without needing a ModelSnippet context. (6-7) Paginator makes it easy to create paginated, user sortable listings. You can use PaginatedSnippet instead of ModelSnippet to help. (8-10) ItemsList lets you manage a list of entities with pending additions and deletions. It's used by TableEditor, which is a very easy to use and customizable snippet to edit tables directly. It's useful for editing short lists, e.g., a lookup table like cities. Don't forget to register the table in Boot. (11) Then there's the experimental FormProcessor, if you need your form to be processed in one block instead of separate closures, e.g., to surround with try. (12) Also experimental is sitemap.XmlMenu which lets you write menus in xml. (13) I may add CaseEnum, which lets you write case classes that automatically double as an Enumeration. Questions, comments, suggestions, and constructive criticism are more than welcome! Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: New features
I will try but I may not have a chance in the next few days. I did write up scaladocs, although I haven't pushed some clarifications for TableEditor. You probably don't want to use XmlMenu, but David said I may as well throw it in. The advantage is if you want to read it in from an xml file. - marius d.marius.dan...@gmail.com wrote: Would you please add some examples on the wiki so that people can actually visualize how these things can be used? As far as XmlMenu goes why do we want to express menus as xml ? Br's, Marius On Jul 27, 10:57 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed some code last night, which can help building mapper-based view snippets, with G-d's help. It includes the following classes: (1-2) net.liftweb.mapper.OneToMany, ManyToMany: Gives a more object-oriented approach to managing related entites. You can manage the many side of a 1-n and n-n as a mutable collection of children, and the parent of a child can be set directly, instead of via its id. And the children are not saved to the database when you add them until you call save on it or its parent, nor deleted when you remove tem until you call delete_!, which is very helpful when you need to keep track of adds/removes through multiple requests. For example, if you are displaying a list and you can click delete, but it shouldn't be permanently deleted until you click save. There is a new package, ...mapper.view, which contains a number of utilities for mapper-based views: (3-4) ModelView and ModelSnippet provide a number of building blocks for views that are too complex to CRUDify. Inherit ModelSnippet (which extends StatefulSnippet) and wrap your entities in ModelView (view is used in the sense of a wrapper). (5) Util provides some more building blocks that just be imported, without needing a ModelSnippet context. (6-7) Paginator makes it easy to create paginated, user sortable listings. You can use PaginatedSnippet instead of ModelSnippet to help. (8-10) ItemsList lets you manage a list of entities with pending additions and deletions. It's used by TableEditor, which is a very easy to use and customizable snippet to edit tables directly. It's useful for editing short lists, e.g., a lookup table like cities. Don't forget to register the table in Boot. (11) Then there's the experimental FormProcessor, if you need your form to be processed in one block instead of separate closures, e.g., to surround with try. (12) Also experimental is sitemap.XmlMenu which lets you write menus in xml. (13) I may add CaseEnum, which lets you write case classes that automatically double as an Enumeration. Questions, comments, suggestions, and constructive criticism are more than welcome! Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: New features
Sounds great. I've been using hacks such as adding code like this to my mapper classes just to create a Many-to-Many relationship between say, tag and content tables (using an intermediary ContentTag table). Similarly, I've done User/Roles relationships. private object _dbTags extends HasManyThrough(this, Tag, ContentTag, ContentTag.content, ContentTag.tag) private[model] var _tags : List[Tag] = _ private val locker = new Object def tags : List[Tag] = locker.synchronized { if(_tags eq null){ _tags = _dbTags() } _tags } def tags(newTags:String) = locker.synchronized { _tags = newTags.roboSplit(,).map(Tag.byName(_)) this } def tags(newTags:List[Tag]) = locker.synchronized { _tags = newTags this } def tagsToo:List[Tag] = ContentTag.findAll(By(ContentTag.content, this.id)).map(_.tag.obj.open_!) def showTags = Text(tags.map(_.name.is).mkString(, )) But, then I have to add code like this to the meta-mapper objects: def addTags(entry: Content) { if(entry._tags ne null){ entry._tags.foreach(ContentTag.join(_, entry)) } } def delTags(entry:Content) = ContentTag.findAll(By(ContentTag.content, entry)).foreach (_.delete_!) It's not very pretty. Nor easy to duplicate. I hope your new code is considerably less messy. Is it in the repo-snapshot repository yet. On Jul 27, 12:57 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed some code last night, which can help building mapper-based view snippets, with G-d's help. It includes the following classes: (1-2) net.liftweb.mapper.OneToMany, ManyToMany: Gives a more object-oriented approach to managing related entites. You can manage the many side of a 1-n and n-n as a mutable collection of children, and the parent of a child can be set directly, instead of via its id. And the children are not saved to the database when you add them until you call save on it or its parent, nor deleted when you remove tem until you call delete_!, which is very helpful when you need to keep track of adds/removes through multiple requests. For example, if you are displaying a list and you can click delete, but it shouldn't be permanently deleted until you click save. There is a new package, ...mapper.view, which contains a number of utilities for mapper-based views: (3-4) ModelView and ModelSnippet provide a number of building blocks for views that are too complex to CRUDify. Inherit ModelSnippet (which extends StatefulSnippet) and wrap your entities in ModelView (view is used in the sense of a wrapper). (5) Util provides some more building blocks that just be imported, without needing a ModelSnippet context. (6-7) Paginator makes it easy to create paginated, user sortable listings. You can use PaginatedSnippet instead of ModelSnippet to help. (8-10) ItemsList lets you manage a list of entities with pending additions and deletions. It's used by TableEditor, which is a very easy to use and customizable snippet to edit tables directly. It's useful for editing short lists, e.g., a lookup table like cities. Don't forget to register the table in Boot. (11) Then there's the experimental FormProcessor, if you need your form to be processed in one block instead of separate closures, e.g., to surround with try. (12) Also experimental is sitemap.XmlMenu which lets you write menus in xml. (13) I may add CaseEnum, which lets you write case classes that automatically double as an Enumeration. Questions, comments, suggestions, and constructive criticism are more than welcome! Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: New features
I committed it last night, so I think it should be there. To use many-to-many, simply mix ManyToMany to your mapper, then create a MappedManyToMany field like any other field. See the scaladocs for specifics. Then in your view you can use the field like a collection, e.g., remove an element with -=, and save the mapper to apply the changes. - glenngl...@exmbly.com wrote: Sounds great. I've been using hacks such as adding code like this to my mapper classes just to create a Many-to-Many relationship between say, tag and content tables (using an intermediary ContentTag table). Similarly, I've done User/Roles relationships. private object _dbTags extends HasManyThrough(this, Tag, ContentTag, ContentTag.content, ContentTag.tag) private[model] var _tags : List[Tag] = _ private val locker = new Object def tags : List[Tag] = locker.synchronized { if(_tags eq null){ _tags = _dbTags() } _tags } def tags(newTags:String) = locker.synchronized { _tags = newTags.roboSplit(,).map(Tag.byName(_)) this } def tags(newTags:List[Tag]) = locker.synchronized { _tags = newTags this } def tagsToo:List[Tag] = ContentTag.findAll(By(ContentTag.content, this.id)).map(_.tag.obj.open_!) def showTags = Text(tags.map(_.name.is).mkString(, )) But, then I have to add code like this to the meta-mapper objects: def addTags(entry: Content) { if(entry._tags ne null){ entry._tags.foreach(ContentTag.join(_, entry)) } } def delTags(entry:Content) = ContentTag.findAll(By(ContentTag.content, entry)).foreach (_.delete_!) It's not very pretty. Nor easy to duplicate. I hope your new code is considerably less messy. Is it in the repo-snapshot repository yet. On Jul 27, 12:57 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I committed some code last night, which can help building mapper-based view snippets, with G-d's help. It includes the following classes: (1-2) net.liftweb.mapper.OneToMany, ManyToMany: Gives a more object-oriented approach to managing related entites. You can manage the many side of a 1-n and n-n as a mutable collection of children, and the parent of a child can be set directly, instead of via its id. And the children are not saved to the database when you add them until you call save on it or its parent, nor deleted when you remove tem until you call delete_!, which is very helpful when you need to keep track of adds/removes through multiple requests. For example, if you are displaying a list and you can click delete, but it shouldn't be permanently deleted until you click save. There is a new package, ...mapper.view, which contains a number of utilities for mapper-based views: (3-4) ModelView and ModelSnippet provide a number of building blocks for views that are too complex to CRUDify. Inherit ModelSnippet (which extends StatefulSnippet) and wrap your entities in ModelView (view is used in the sense of a wrapper). (5) Util provides some more building blocks that just be imported, without needing a ModelSnippet context. (6-7) Paginator makes it easy to create paginated, user sortable listings. You can use PaginatedSnippet instead of ModelSnippet to help. (8-10) ItemsList lets you manage a list of entities with pending additions and deletions. It's used by TableEditor, which is a very easy to use and customizable snippet to edit tables directly. It's useful for editing short lists, e.g., a lookup table like cities. Don't forget to register the table in Boot. (11) Then there's the experimental FormProcessor, if you need your form to be processed in one block instead of separate closures, e.g., to surround with try. (12) Also experimental is sitemap.XmlMenu which lets you write menus in xml. (13) I may add CaseEnum, which lets you write case classes that automatically double as an Enumeration. Questions, comments, suggestions, and constructive criticism are more than welcome! Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---