I have a template handler that I''ve registered with register_template_handler. However, I am having a problem getting instance variables from the controller. The view that is passed in has the instance variables from the scaffolding, but not those that I define outside of it. Example: in the "stories" controller, I have a variable @strories. This is actually set by the scaffold code. In the view''s assigns in the template handler, sure enough, there is an entry with the key ''stories.'' However, when I set another variable @page, no entry appears in the assigns hash. Why does @stories get propagated but not @page? How can I remedy this? TIA, Dan
A quick follow-up: I have traced this all through the code as best I can and noticed a couple of things. First, the delegation to the template handler does not provide access to the current bindings, as do the rhtml and xml handlers. So obviously, this must be done explicitly. The view is provided to the handler''s constructor for this purpose. However, it is clearly not the same view as the one being used by the controller to render the template. In other words, the view that is passed to the handler on initialization is no longer valid - another one has been created apparently. Thus, changes to the controller''s data are not accessible directly to the template handler. I am not sure exactly what the right way to fix this would be (or if I truly have grasped the problem). Suggestions, hints, etc., welcome! TIA, Dan
cancel all that ... rookie mistake, actually i hadn''t realized that redirects lose instance variables. in thinking about it, it''s obvious. i did some further traces and it turns out the handlers and views are constructed fresh every time. so they are always in synch, but there is minimal state kept from request to request. flash can be used for keeping something around for a single request. session variables can be used if more is needed. i had been working on a prior framework where i had gone to great lengths to keep state in the session. there were even different levels of caching (global, user, session, etc.) that could be automatically associated with different types. it was very complex and very difficult to tune performance-wise. so keeping it simple here is a very valid approach. still, i''m torn on this. part of the advantage of oop is that it binds state and behaviors. in the java world, for example, state is maintained quite transparently in memory. caching is typically implemented at each level and it is all pretty non-intrusive. so i have continued to aspire to that (speaking purely in terms of maintaining state in web apps). the key to making this easy, of course, is that the objects must stay in memory. ruby is so much more expressive and fluid than java, it seems a shame that we can''t do this. has any thought been given to how to do this in ruby? does fast cgi lend itself to this? or is it a question of caching appropriately? or is it just not worth it? Dan
> > still, i''m torn on this. part of the advantage of oop is that it binds > state and behaviors. in the java world, for example, state is > maintained quite transparently in memory. caching is typically > implemented at each level and it is all pretty non-intrusive. so i > have continued to aspire to that (speaking purely in terms of > maintaining state in web apps). > > the key to making this easy, of course, is that the objects must stay > in memory. ruby is so much more expressive and fluid than java, it > seems a shame that we can''t do this. has any thought been given to how > to do this in ruby? does fast cgi lend itself to this? or is it a > question of caching appropriately? or is it just not worth it? > >In my experience Java developers face the same issues as everyone else - unless you are talking about rich clients, which is a different ball of wax.The problem doesn''t have much to do with Java or Ruby - what we''re always dealing with is the essential statelessness of HTTP. Every web framework will need to make a set of decisions about how to deal with this that will have pros and cons. Some ways of doing it will serve certain purposes and applications better than others, but there is no magic bullet. You can put an object graph into @session and have your controller retrieve it for you - just be aware of the existence of the back button and the fact that users can invoke actions outside your conceived workflow by use of bookmarks or even typing URLs - the user can put themselves into a state that your server is unaware of. Even ignoring this problem for the framework to automatically keep every object in memory for the life of the session would seriously hurt scalability. Web apps don''t need *everything* kept in memory for each user. Despite the original design concept, in J2EE very little use has actually been made of stateful session beans - instead the web tier typically maintains the little bit of state required with a combination of objects held in memory and the form state. ASP.NET (and, I believe, JSF) put a lot of extra state into hidden form fields to simplify the programming model - at the expense of larger postbacks. This is one of the easiest approaches though, because it pretty much guarantees that the state is driven from the state of the client. I think a good compromise is to use cookies and form variables to track the workflow state and a small object graph in @session or even serialized to a cookie to store personalization, entitlement information etc, and leave the bulk of the domain objects in the database. Databases are really good at caching and optimizing based on workload and usage patterns, and with a good O/R framework like ActiveRecord you still have a nice OO programming model. No matter which approach you take, the programmer either has to be aware of state or has to pay a very steep price for ignorance.