What I'm trying to do is implement list and tree-like behavior via a trait.

I want to create an object, say a Whatsit. And then I want to be able to 
say that Whatsits have list-like behavior by mixing in an ActsAsList 
trait (similar to the way Rails does it).

so my class might be

class Whatsit extends ActsAsList...

And this trait would automatically add attributes and methods to permit 
list-like behavior, for example:

def moveUp
def moveDown
def moveToTop
def moveToBottom
def isFirst
def isLast

and so on. So then when I created and persisted a new Whatsit, it would 
automatically be added at the end of the list. Then I could call 
moveToBefore(other) to position it right before "other" in the list.

Same idea with trees, etc.

I use lists and trees a lot, so I'd love to be able to just add a trait.

The obvious way to do this in Java is through a DAO, but I've avoided 
all that boilerplate in Scala and would like to continue to do so.

This is one area, IMO, that Record/Mapper could beat the pants off of 
Hibernate. Maybe someone has already done this in Hibernate, but I can't 
find it.

Chas.

Kris Nuttycombe wrote:
> On Wed, Jan 14, 2009 at 5:02 PM, Charles F. Munat <[email protected] 
> <mailto:[email protected]>> wrote:
> 
> 
>     Excellent. Your reasons for using POJOs make perfect sense, and none of
>     them have any relevance for me, which means that for my apps -- which
>     are relatively pure Scala -- I'm on the right track.
> 
>     Thanks again. This really helps.
> 
>     Now if I could just get Hibernate to permit one entity to manipulate
>     another without going through an EntityManager, I'd be in heaven.
> 
> 
> What sort of manipulation are you interested in? If you have your 
> cascades set up correctly, you usually don't need to involve an 
> EntityManager - the persistence layer gets updated correctly when the 
> transaction associated with the request completes. The only bit I'm not 
> sure about with that is the behavior of removes.
> 
> Kris
> 
> 
>     Chas.
> 
>     Kris Nuttycombe wrote:
>      > I'm not sure it's that thorough; it's just a copy/paste from my
>     app. :)
>      >
>      > The reason that the entities are POJOs is simple; the Lift app is
>     simply
>      > a small internal administrative interface for a much larger Java EE
>      > application. I've toyed with the possibility of porting as much
>     of the
>      > main app as possible to Scala, but there's just no time to do it.
>     Also,
>      > I really love having good refactoring support in the IDE, and
>     it's just
>      > not there yet for scala alone, much less hybrid scala/java projects.
>      >
>      > Kris
>      >
>      > On Wed, Jan 14, 2009 at 3:05 PM, Charles F. Munat <[email protected]
>     <mailto:[email protected]>
>      > <mailto:[email protected] <mailto:[email protected]>>> wrote:
>      >
>      >
>      >     Kris,
>      >
>      >     Thank you much for this very thorough exegesis. I'll study it
>     and will
>      >     try to wrap my tiny brain around it. I really appreciate the
>     effort you
>      >     put into it.
>      >
>      >     One question... why did you choose to implement the entities
>     as POJOs
>      >     instead of as Scala objects? I've been working with the
>     latter without
>      >     too much difficulty, and I'd like to avoid writing Java as
>     much as
>      >     possible. Is there some advantage to using POJOs?
>      >
>      >     Chas.
>      >
>      >     Kris Nuttycombe wrote:
>      >      > Hi, Chas,
>      >      >
>      >      > Sorry it's taken me so long to respond to this - I've been
>     pretty
>      >     buried
>      >      > for the past week.
>      >      >
>      >      > Here's an example of what I'm doing:
>      >      >
>      >      >
>      >      > trait Binding {
>      >      >     def apply(xhtml : NodeSeq) : NodeSeq = xhtml
>      >      > }
>      >      >
>      >      > trait EntityBinding[+T] extends Binding {
>      >      >     def entity : T
>      >      > }
>      >      >
>      >      > trait SubscriptionEventBinding extends
>      >     EntityBinding[SubscriptionEvent] {
>      >      >     abstract override def apply(xhtml : NodeSeq) : NodeSeq = {
>      >      >         val transTemplate = chooseTemplate("event",
>      >     "transactions", xhtml)
>      >      >
>      >      >         bind("event", super.apply(xhtml),
>      >      >              "scheduleDate" -> h(entity.getScheduleDate),
>      >      >              "transactions" ->
>      >      > Group(entity.getTransactions.toSeq.flatMap(_(transTemplate)))
>      >      >         )
>      >      >     }
>      >      > }
>      >      >
>      >      > trait BillingEventBinding extends
>      >      > EntityBinding[SubscriptionBillingEvent] with
>      >     SubscriptionEventBinding {
>      >      >     abstract override def apply(xhtml : NodeSeq) : NodeSeq = {
>      >      >         bind("event", super.apply(xhtml),
>      >      >              "detail" -> <span>Charges: ${entity.getCharge};
>      >     Discount:
>      >      > ${entity.getDiscount}</span>,
>      >      >              "type" -> h("Billing"))
>      >      >     }
>      >      > }
>      >      >
>      >      > trait CancellationEventBinding extends
>      >      > EntityBinding[SubscriptionCancellationEvent] with
>      >     SubscriptionEventBinding {
>      >      >     abstract override def apply(xhtml : NodeSeq) : NodeSeq = {
>      >      >         bind("event", super.apply(xhtml),
>      >      >              "detail" -> <div>Reason:
>     {entity.getReason}<br/>Final
>      >      > Balance: {entity.getFinalBalance}</div>,
>      >      >              "type" -> h("Cancellation"))
>      >      >     }
>      >      > }
>      >      >
>      >      > Then, in the appropriate scope, I import the correct implicit:
>      >      >
>      >      >     implicit def entityToEventBinding(e : SubscriptionEvent) :
>      >     Binding = {
>      >      >         e match {
>      >      >             case b : SubscriptionBillingEvent      => new
>      >      > BillingEventBinding        { override val entity = b }
>      >      >             case c : SubscriptionCancellationEvent => new
>      >      > CancellationEventBinding   { override val entity = c }
>      >      >             case _ => throw new
>     IllegalStateException("Unbindable
>      >     event
>      >      > " + e.getClass + " (" + e + ")")
>      >      >         }
>      >      >     }
>      >      >
>      >      > All of the entity classes are JPA entities implemented in
>     Java. If I
>      >      > have a different set of bindings for a different context,
>     I simply
>      >      > create a separate trait. The nice thing about this approach is
>      >     that the
>      >      > traits are stackable over an inheritance hierarchy, as above.
>      >      >
>      >      > With this in place, I can just treat my entity as a binding
>      >     context on
>      >      > its own:
>      >      >
>      >      >   object Subscriptions {
>      >      >     object current extends
>     SessionVar[Box[Subscription]](Empty)
>      >      >   }
>      >      >
>      >      > ... stuff that populates the SessionVar
>      >      >
>      >      >   def events(xhtml : NodeSeq) : NodeSeq = {
>      >      >
>      >      >
>      >    
>     
> Subscriptions.current.is.map(_.events.toSeq.flatMap(_(xhtml))).openOr(h("No
>      >      > subscription to display events for."))
>      >      >   }
>      >      >
>      >      >
>      >      > Kris
>      >      >
>      >      >
>      >      > On Fri, Jan 9, 2009 at 5:29 PM, Charles F. Munat
>     <[email protected] <mailto:[email protected]>
>      >     <mailto:[email protected] <mailto:[email protected]>>
>      >      > <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>> wrote:
>      >      >
>      >      >
>      >      >     That sounds kinda smart. Is there any chance you could
>     post
>      >     some example
>      >      >     code?
>      >      >
>      >      >     Chas.
>      >      >
>      >      >     Kris Nuttycombe wrote:
>      >      >      > Oh, I'm not complaining about the way User is
>     handled - my
>      >      >     response was
>      >      >      > more about the general hate towards MVC upthread.
>     Having a
>      >     sensible
>      >      >      > default for a standard use case is great, even when
>     I'll
>      >     probably
>      >      >     never
>      >      >      > use the default.
>      >      >      >
>      >      >      > In my Lift app, my shortcut to different renderings
>     (well,
>      >     different
>      >      >      > bindings, really) is to keep all the binding logic
>     for a
>      >     specific
>      >      >     case
>      >      >      > in a trait and have an implicit conversion from my
>     model
>      >     to the
>      >      >      > appropriate trait in the relevant scope. You still
>     have to
>      >     do the
>      >      >     work,
>      >      >      > but it makes the bindings a lot easier to reuse.
>      >      >      >
>      >      >      > Kris
>      >      >      >
>      >      >      > On Fri, Jan 9, 2009 at 4:46 PM, Charles F. Munat
>      >     <[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>
>      >      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>
>      >      >      > <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>
>      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>>> wrote:
>      >      >      >
>      >      >      >
>      >      >      >     I don't see how you're any worse off if the
>     model can
>      >     render
>      >      >     itself in
>      >      >      >     one way. And if that way is a common
>      >     standards-compliant way,
>      >      >     such as
>      >      >      >     rendering to XML, and you include semantic
>      >     information, then
>      >      >     you can
>      >      >      >     layer any other layers you want on top to do the
>      >     mapping to
>      >      >     the 30
>      >      >      >     different contexts.
>      >      >      >
>      >      >      >     Saying that an object should know how to render
>     itself
>      >     to some
>      >      >      >     universally recognized format is not the same as
>      >     saying that
>      >      >     that solves
>      >      >      >     all rendering issues.
>      >      >      >
>      >      >      >     Is there some shortcut to 30 different
>     renderings that I'm
>      >      >     missing, or
>      >      >      >     do you have to do the work either way?
>      >      >      >
>      >      >      >     Chas.
>      >      >      >
>      >      >      >     Kris Nuttycombe wrote:
>      >      >      >      > If you want to render a model 30 different
>     ways in 30
>      >      >     different
>      >      >      >      > contexts, it kind of sucks though, doesn't it?
>      >      >      >      >
>      >      >      >      > Or what if, shock horror, you don't know how the
>      >     eventual
>      >      >     system is
>      >      >      >      > going to want to render the model (i.e., the
>     person
>      >     doing the
>      >      >      >     rendering
>      >      >      >      > won't be able to change the model code.) Not too
>      >     uncommon, I
>      >      >      >     don't think...
>      >      >      >      >
>      >      >      >      > Kris
>      >      >      >      >
>      >      >      >      > On Sun, Jan 4, 2009 at 9:58 AM, Michael
>     <mike.sr <http://mike.sr>
>      >     <http://mike.sr>
>      >      >     <http://mike.sr> <http://mike.sr>
>      >      >      >      > <http://mike.sr>@gmail.com
>     <http://gmail.com> <http://gmail.com>
>      >     <http://gmail.com>
>      >      >     <http://gmail.com> <http://gmail.com>>
>      >      >      >     wrote:
>      >      >      >      >
>      >      >      >      >
>      >      >      >      >      > Also I was looking at the sample model
>      >     source code
>      >      >     (User,
>      >      >      >     ProtoUser)
>      >      >      >      >      > and saw presentation logic mixed in it.
>      >     Shouldn't the
>      >      >      >     business and
>      >      >      >      >      > model logic be kept separated from the
>      >     presentation
>      >      >     logic
>      >      >      >     or is there
>      >      >      >      >      > a Lift strategy it?
>      >      >      >      >
>      >      >      >      >     Hmm, a model that can render itself ...
>     That sounds
>      >      >     like this
>      >      >      >     crazy
>      >      >      >      >     paradigm called object-oriented programming.
>      >     Some radicals
>      >      >      >     say it has
>      >      >      >      >     some advantages over the more procedural
>     style
>      >     of MVC.
>      >      >      >      >
>      >      >      >      >     -- Michael
>      >      >      >      >
>      >      >      >      >
>      >      >      >      >
>      >      >      >      >
>      >      >      >      > >
>      >      >      >
>      >      >      >
>      >      >      >
>      >      >      >
>      >      >      > >
>      >      >
>      >      >
>      >      >
>      >      >
>      >      > >
>      >
>      >
>      >
>      >
>      > >
> 
> 
> 
> 
> > 

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to