I'm not by any means the expert on Jifty, but I've given my thoughts below.<br><br>On 8/14/07, <b class="gmail_sendername">Stéphane Alnet</b> <<a href="mailto:stephane@carrierclass.net">stephane@carrierclass.net
</a>> wrote:<div><span class="gmail_quote"></span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Hello,<br><br>Sorry for the long email. I'm new to Jifty and wanted to evaluate the
<br>complexity of implementing some of the things I need in my application<br>before "making the move". I especially need:<br><br>(1) Adding constraints on SQL queries:<br><br> I need to be able to filter the display and restrict the insertion
<br>of the content of all Models based on which "group" a user belongs to<br>(groups are stored in the Model alongside the users). Some key SQL<br>tables in my model contain a "group_id/owner_id" pointer to the group
<br>that owns subsets of records (it doesn't make sense in the model to<br>have all tables have an owning "group" because external dependencies<br>dictate what can be viewed/modified from that selected set of SQL
<br>tables). I already have code that generates SQL fragments on-the-fly<br>to do cross-table constraints (for example, user A can see records<br>WHERE external_id IN (SELECT id FROM external_table WHERE group IN<br>(SELECT group FROM group_user WHERE user = $user)), etc.), but I'm
<br>fine with using something better inside Jifty.<br><br> Is this what RightsFrom implements?<br> RightsFrom seems to only care about "users", not "groups", how<br>should I extend this cleanly to support "groups"?
</blockquote><div><br>I'm not precisely clear about what RightsFrom does. To quote the comments in the code "this card is bloody hard to follow. it's my fault. --jesse" I believe the intention is to basically let you do to the current record whatever you can do to the linked record. However, Jesse or someone with a longer history with Jifty can probably give you more detail.
<br><br>The key to determining whether you can do something in Jifty is defining a current_user_can() method in your models. You can define a common one for all your models by simply adding a definition to you MyApp::Record class. If you have a couple different sets you use, you could use additional custom base classes as well. I'd recommend starting with Jifty::Manual::AccessControl if you have not already.
<br><br>I also highly recommend building up some handy shorthand methods in MyApp::CurrentUser to handle things like testing in_group() and is_owner_of() to help write your current_user_can() methods.<br></div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
(2) Implementing changesets:<br><br> I need to provide the ability to do different things which end up<br>being basically the same thing:<br> - Undo: must be able to reverse a change that was previously done;<br> - Change Control / Policy reviews: a change done by an actor
<br>(user) A may be subject to review by another user B (or a chain / set<br>of actors);<br> - Timed changes: changes are applied at a given date and time (for<br>example for contractual reasons).<br><br> The way I decided to implement this is to define what I call
<br>"ChangeSet"s which basically record the changes that would have been<br>done in the database (which table and columns would have been<br>modified, what are the old and new values, etc.), and depending on the
<br>result to be obtained (simple Undo, Change Control review, timed) will<br>(respectively) apply the ChangeSet immediately, after review, or at a<br>given time (controlled externally).<br><br> In turn, a "commit" of a changeset generates an INSERT/UPDATE
<br>using the "new" values in the ChangeSet (for create/modify), or<br>marking a record as inactive (for delete). Conversely an Undo<br>(reversal) of a changeset involves marking the record inactive (for<br>create), generating an UPDATE using the "old" values in the ChangeSet
<br>(for modify), or marking the record active (for delete); etc.(*)<br><br> To achieve this I need to be able to:<br><br> (a) mark records in the database as active/inactive; only "active"<br>records should be visible within Jifty. My understanding is that the
<br>simplest way to do add such a field is to create a Mixin and use it in<br>each model in my application (the mixin basically adds a boolean<br>"active" column, ..).<br><br> How would I then filter the records avaible within Jifty?
<br> Is there a way to implement this within the mixin (i.e. drop<br>the record if "active is not true")?</blockquote><div><br>I can think of one good way. In general, whenever you need to iterate through a collection of models you do one of two things. You always start by creating a new collection object and then you either call unlimit() to fetch all records or call limit() one or more times to limit which records to fetch.
<br><br>I would suggest overriding the collection object for the ChangeSet model and then add a limit_to_active() method to use in place of unlimit(). That would make it easy and self-documenting without having to type $collection->limit(column => 'active', value => 0) every time. If you need this for every class in your application, just throw the limit_to_active() method into MyApp::Collection and add the active column to a schema into a mixin included with all your classes (you could even add it to a schema block in MyApp::Record, but intuition tells me that you rarely need to add a column to every single model).
<br></div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"> (b) replace the standard create/modify/delete in Jifty by versions<br>that implement the ChangeSet mechanism (except for private Jifty
<br>tables and the changeset tables themselves).<br><br> Would creating appropriate delete(), insert() and<br>update_record_value() in MyApp::Handle be sufficient?</blockquote><div><br>Without knowing more about what you're doing here, I'm not sure what to recommend. There is some work involving records with built-in versioning being done, but it's in a branch and not finished at this time.
<br><br>The way it works (last I looked) was to actually store old versions of the records away in Subversion, but I don't know what state it's in now, how serious the implementation is, what it's capable of doing to restore old versions, what the performance characteristics are or anything else. But there has been some work at handling record revisions as a built-in feature of Jifty.
<br><br>I don't know if that's even compatible with your ideas of ChangeSets, but since I can't answer the question properly, I thought I'd at least let you know about something that sounds similar. And, I haven't taken the time to look over what you've put up on google code. :(
<br></div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">(3) Hiding parts of forms based on a form field:<br><br> I need to show different forms based on the value a user selected
<br>in a field (for example I have a SQL table that store information for<br>different types of trunks; the parameters for each class of trunks are<br>independent; this is similar in spirit to PostgreSQL's INHERIT<br>
mechanism). I've seen Jifty::Manual::PageRegions; but I'm not sure how<br>to use that kind of technics to bind a field (generated by Jifty based<br>on the Model) to showing/hiding a region on the web interface, or
<br>forcing/disabling the validation of field in the Model.<br><br> What is the proper way of implementing this?</blockquote><div><br>I'm not certain if Jifty supports a way to do this, but adding in the necessary JavaScript shouldn't be difficult:
<br><br>// in share/web/static/js/app_behaviour.js<br>Behaviour.apply({<br> 'input.argument-my_radio': function(e) {<br> e.onclick = function() {<br> if (this.value == 'X') { Element.show
($('subform-X')); Element.hide($('subform-Y')); }<br> if (this.value == 'Y') { Element.show($('subform-Y')); Element.hide($('subform-X')); }<br> };<br> },<br> '
div.subform': function(e) { Element.hide(e); }<br>});<br><br>I would then wrap those parts of the form in divs marked with "subform-X" and "subform-Y" IDs and "subform" classes.<br><br>If Jifty doesn't already have a way to do this for you, it'd be nifty to have a subform plugin for this sort of thing.
<br><br>Anyway, I hope at least some of this has been helpful.<br><br>Cheers,<br>Andrew<br></div></div>