Wonder how pylons people deal with the subj.
Suppose entity A has OneToMany relation to entity B. What is the best
practice to represent the relation in show/edit templates?
Of particular interest are perspectives *to reuse* B show/edit
template in div/iframe of A show/edit template. Are there chances to
work out sufficiently generic template to show any entity?
--
Vladimir
Hi Vlad.
While I'm probably the least experienced person on this list, in my
apps I tend to create generic CRUD (Create Read Update Delete)
functionality.
That is, I create a controller plus templates that given any model
class/object, will introspect it (or will get the columns and their
corresponding types from an appropriate description/annotation) and
create a form for each of C,R,U,D (actually one with different actions
available)
In the case of relations I tend to allow many-to-one relations to be
edited in the many end (i.e. the model class where the foreign key is
stored).
Given A(id, fk_b_id), B(id), with A.b holding a reference to a B
object via the A.fk_b_id foreign key ('many' end of relationship), and
B.list_of_a holding a list of references to objects of A (the 'one'
end of relationship), I tend to put a combobox in the form for A,
allowing it to select one of the available B objects. I also tend not
to put some kind of multiple select list in the form for editing B
since many of my users may not know how to select multiple entries in
such a control (by holding Ctrl down).
This setup is similar, but much less generic, to the CatWalk app which
featured in Turbogears.
I use formalchemy for that.
> In the case of relations I tend to allow many-to-one relations to be
> edited in the many end (i.e. the model class where the foreign key is
> stored).
I see. But this doesn't suit well in many cases. A common task is to
attach many (non-existing yet) objects to one-end object. Many-end
objects are created in process of editing. What could be the pattern?
> Given A(id, fk_b_id), B(id), with A.b holding a reference to a B
> object via the A.fk_b_id foreign key ('many' end of relationship), and
> B.list_of_a holding a list of references to objects of A (the 'one'
> end of relationship), I tend to put a combobox in the form for A,
> allowing it to select one of the available B objects. I also tend not
> to put some kind of multiple select list in the form for editing B
> since many of my users may not know how to select multiple entries in
> such a control (by holding Ctrl down).
Multiselect is evil here. Non-informative and is total foobar when the
number of items is sufficiently big. One click by mistake and all your
selection blown. Plus, no edit capabilities. Imagine a list of
attached images, which you want to CRUD.
Natural widget here is the sub-grid, IMHO. With formalchemy it is
_already_ known (by introspection, or via manual configuration) how to
display unconstrained (by the relation key) list of objects of type X.
Similarly it is known how to display edit form for objects of type X.
The problem is how to constrain by relation key the list of
subordinate objects Y, put that list verbatim to X edit/new form, and
allow this constraint to propagate to edit/new forms for Y objects. If
it were done, (in theory, I admit) a developer could relay the most of
configuration to formalchemy engine, thus generalizing the interface.
--
Vladimir
Stuff like using a datagrid (controlling a 1-M from the one side) or a
drop-down / select box (controlling a 1-M from the many side) are just
two possible ways that this can be dealt with, and there's no way you
can look at a 1-M relationship in the database and figure out what's
best. You can guess, but that's all you're doing: guessing. You really
find out by talking to the user of your application. Sometimes an
entity and it's children can be so large that a data grid would be
unwieldy for the children, but it still makes sense to add modify
children from the parent's page. Here I would put the children in it's
own page/form, which is reachable from a link or button on the
parent's admin page.
The advantage to this approach is that the individual forms are
typically just one entity, and thus simpler. The disadvantage is that
the user might take more clicks to get to what you they want to edit.
But in the end, you can't have one "pattern" to do it all. Just
because you've found/made a great hammer doesn't mean you should be
hammering in screws.
Now, if you're talking about a specific situation, such as "Creating a
form for the parent along with a datagrid for all the children all on
one page", then we can talk implementation. But I don't think that
this theorizing on one way to implement the interface for a
one-to-many relationship has a true answer.
--
Mark Hildreth
263 Kibbe Rd.
East Longmeadow, MA 01028
(413) 883-9139
mark.k....@gmail.com
Thanks for feedback.
> I think too often we look at how to best do our job by using a tool to
> get our database into the form of an html form. If you take the time
> to learn the tools, then this can work for you. The problem is that
> often we're so mired in getting this kind of stuff to work
> automagically that we forget that the end result is to make software
> for the end user, not for the database.
Right! I am the user and I speak for formalchemy.
>
> Stuff like using a datagrid (controlling a 1-M from the one side) or a
> drop-down / select box (controlling a 1-M from the many side) are just
> two possible ways that this can be dealt with, and there's no way you
> can look at a 1-M relationship in the database and figure out what's
> best.
Reasonably small record count, reasonable small fields count -- these
could be the criteria of *boxes.
But presenting hundreds of unmanageable (no filtering, no sorting, no
nothing) records in *boxes is unlikely a good practice.
> You can guess, but that's all you're doing: guessing. You really
> find out by talking to the user of your application.
I *am* the user. And am trying to reflect what would it be the most
comfortable to me to deal with.
> Sometimes an
> entity and it's children can be so large that a data grid would be
> unwieldy for the children, but it still makes sense to add modify
> children from the parent's page. Here I would put the children in it's
> own page/form, which is reachable from a link or button on the
> parent's admin page.
I'm inclined to do so, but still as the user I want related stuff be
visible on parent view. May be partially, but visible.
>
> The advantage to this approach is that the individual forms are
> typically just one entity, and thus simpler.
Right. One entity -- one form, and one grid (list). But take that 1-M
relation is a _field_, not entity. Ans as a field it should have
renderers: read-only to display in grids, read-write to display on
forms. I'm asking for an advice, whether read-only 1-M field renderer
should trivially be the filtered (by relation key) grid for M-end
entity.
> The disadvantage is that
> the user might take more clicks to get to what you they want to edit.
I can live with that, but if we take that related stuff should be
visible on parent view, the synchronization problem arises. And the
solutions to it tend to be ugly (reload of the parent page, often,
which hits usability).
> But in the end, you can't have one "pattern" to do it all. Just
> because you've found/made a great hammer doesn't mean you should be
> hammering in screws.
>
Right. But deduction (in sense of customizing a good guess) is the
primary technique of my development paradigm. Formalchemy does much of
guessing, the missing part is guessing on displaying 1-M relations.
> Now, if you're talking about a specific situation, such as "Creating a
> form for the parent along with a datagrid for all the children all on
> one page", then we can talk implementation.
Exactly. Suppose I want to CRUD images related to an object. The
situation is hardened here since images (along with other uploaded
stuff), as indirectly accessed objects, should in addition be provided
with interface to upload them. How would you do that?
TIA,
--
Vladimir
> Right! I am the user and I speak for formalchemy.
I'm not sure what you mean when you say "speak for formalchemy".
> I'm inclined to do so, but still as the user I want related stuff be
> visible on parent view. May be partially, but visible.
You can still make it visible, but not editable. Just do it in the
templates. I don't see why you need to make a "read-only renderer" to
do this instead of just doing the rendering directly in a template,
perhaps using a helper function for stuff such as rendering
dates/times or slightly more complex HTML. For forms, I can understand
using something like a form library to help with rendering as you want
to make sure you have a simple way to serialize the form results into
an entity. But for strictly read-only text or other HTML that isn't
fields on a form, I'd just keep that to the template.
>
> Exactly. Suppose I want to CRUD images related to an object. The
> situation is hardened here since images (along with other uploaded
> stuff), as indirectly accessed objects, should in addition be provided
> with interface to upload them. How would you do that?
>
I am not understanding you fully. My main worry is that you're trying
to take DRY too far, which is a problem that that I know hounded me
for awhile, and still sneaks into my thought process. But I guess it
would be helpful to know your use case a little better.
I meant I'm using formalchemy to deal with my forms, I like it and
want to make my job with help of it. Suppose that is the rule of the
game.
>> I'm inclined to do so, but still as the user I want related stuff be
>> visible on parent view. May be partially, but visible.
>
> You can still make it visible, but not editable. Just do it in the
> templates. I don't see why you need to make a "read-only renderer" to
> do this instead of just doing the rendering directly in a template,
> perhaps using a helper function for stuff such as rendering
> dates/times or slightly more complex HTML. For forms, I can understand
> using something like a form library to help with rendering as you want
> to make sure you have a simple way to serialize the form results into
> an entity. But for strictly read-only text or other HTML that isn't
> fields on a form, I'd just keep that to the template.
>
formalchemy is a form library. It introduces "fieldsets", which can be
rendered. Each field composing a fieldset has mentioned two renderers.
The process of visualing of fieldset is just iterative calls to these
renderers. So in this coordinate system 1-M relation is field and, to
avoid inconsistency, I should provide these renderers. Formalchemy'
defaults here to render a multibox.
I consider this widget as foobar, so let's invent a better
presentation. The low-hanging fruit is to *reuse* fieldset renderer of
related entity. The question is how to determine the boundary
conditions of this approach.
>>
>> Exactly. Suppose I want to CRUD images related to an object. The
>> situation is hardened here since images (along with other uploaded
>> stuff), as indirectly accessed objects, should in addition be provided
>> with interface to upload them. How would you do that?
>>
>
> I am not understanding you fully. My main worry is that you're trying
> to take DRY too far, which is a problem that that I know hounded me
> for awhile, and still sneaks into my thought process.
Yes. I hate repetitive mess like copy-pasting.
> But I guess it
> would be helpful to know your use case a little better.
>
Well, a variable length attachment list connected to a particular
entity of my model. It is in fact *the main* column of the entity. To
be specific, a property object is stored along with scan-copies of
related documents. The assumption is that potentially several hundreds
of them can exist. Each attachment should be commented, filtered,
sorted, easily accessible with a click. A strong condition of
no-page-reloads is set.
My first thought was to trick and to wrap such a "bad" data in a
simple <textarea/> with some kind of JS rich editor :) This would
solve at least two problems: arbitrary commenting and ease of access.
I advanced there, but still filter/sort remains.
What could be done here?
TIA,
--
Vladimir