Forum OpenACS Development: acs_atributes usage ?
this may be a dumb question, but i have not figured out how the
attributes i define on object_types that i create, are used in
for example i created a learning resources collection type, subtyped
it with an exam resources collection type and created tables for
both. of course i also created attributes (eg. points,
allowed_time, ... ) for the object types. but what does openacs do
with this information ? does it provide special services for
manipulating attibutes ?
or is it the openacs way to mantle an update query on a single column
of an object with a "set_attribute function" for its object_type?
can someone point me to a really good example of what these
attributes can be used for ?
When the kernel developers (ACS classic) built the kernel they thought it would be nice to have attributes for tables so (for example), the templating system could use those to auto-create forms.
Of course this never happened.
There are in essence two types of attributes that are supported, those that are stored in your type's custom table and those stored in acs_attributes. The reason for the latter is to allow for attributes that can have multiple values.
The first type are almost uniformly set by explicit updates on the table within the toolkit rather than set by the slower "set_attribute" method (if you change more than one attribute, the latter approach will result in multiple updates, *slow*).
So you can think of the attributes stuff serving a descriptive rather than functional purpose for attributes of that type. As Jon mentions, they make possible the auto-generation of forms by the templating engine and similar things. We might want to explore this in the future.
The second type - attributes that can have multiple values and are stored in the attribute values table - is hardly used, and that's just as well IMO. The only way to set such an attribute or get values is through the attributes API.
I haven't had time to go through all this in exhaustive detail, but for our second development/release cycle I've been thinking we might want to get rid of the second type of attribute altogether and maintain the first type strictly for descriptive purposes, i.e. to give a db-independent way to autogenerate forms and the like.
I think it makes sense to use the RDBMS as an RDBMS rather than to try to totally hide it in an abstract object-attribute model. If the entire toolkit lived within the object-attribute model it would be substantially slower (which is probably why various aD implementors used UPDATE directly in their code for attributes stored in the type's custom table).
recording attributes of objects which are unknown at design time.
The choice comes down to: 1. alter tables at runtime to add extra
columns, or 2. model the RDBMS in the RDBMS. There are
advantages and disadvantages to both approaches. (The old aD
KM bboard has some interesting perspective on this, as they
switched between the two methods).
The simple-survey package re-implements such an attribute system
for it's questions and answers. ACS3 has a simillar system for
custom information to be gathered for groups and groups types.
The old event module allows administrators to define custom
attributes for activities and events. Each of these packages
re-implements the same set of features (with a new set of bugs).
Problems with the current acs_attributes system include:
Everything has to be coerced into a clob. I think there's a comment
in the code about this, it shouldn't be too difficult to switch to a
simple-survey-like integer_answer, date_answer etc. set of
columns. Only objects can have attributes, not object types. I
would really like to see
acs_object_types become acs_objects themselves. (Add more
So, I'd rather not see the acs_attributes system dissapear. It needs
to be fixed, enhanced, and used extensively.
I was thinking of its use in the static datamodel, not for the dynamic extension. But one could provide a generalized facility based on "alter table" (which is what 3.x user group types do).
The "alter table" approach doesn't work for multi-valued attributes, of course, unless you added enough weirdly-named columns to support the maximum number of values or abandoned standard SQL features entirely (i.e. use PG arrays).
So I guess a more accurate statement would be that we could get rid of the attribute values table if we did not support multi-valued attributes. Perhaps it wouldn't be worth it ... as I said I haven't looked into this in great detail yet.
1. All the base objects need to have the correct attributes
2. The rapid prototype package needs to be fully functional
3. You need to be about to use objects inside other objects
4. The object system need to be integrated with the templating system
so you can auto generate user interfaces.
5. (optional) You should be able to generate/insert XML schema and documents from any acs object.
Lately I've been working on the last three and I should be done by the end of the month (with an oracle acs4.2 version). I'll see about packaging the stuff up and releasing it.
Once you can auto generate forms and mix data from multiple objects the pain of creating objects and attributes is overcome by what you can do with them. If the persmission system could be faster and extended to attributes things could really be interesting.
#5 isn't really a function of the object model - there's nothing preventing an object type's implementor from providing a service contract method to dump the value in XML or create a new instance from XML input. This would be useful but isn't a core datamodel thang.
Let us know when you get your code packaged up so folks can look at it. This is the kind of thing we won't consider until our second development cycle, which (now that documentation's on a roll and the end of our first development cycle in sight) should kick off in a few weeks.
The rapid protyotype package (#2) I picked up off the arsDigita site. It works ok but the code it generates requires some hand editing to work. Again not a big deal it just needs some work.
By #3 I mean you need to be able to create an object that consists of other objects. For example a contact could be a person, address and phone number. So in the system I'm working on you create an object called Contact and give it 3 attributes Person, Address and Phone Number. The datatypes are person, address and phone_number. You might set max_n_values like person 1, address 3 phone 5. That way one person can have 3 address and 5 phone numbers.
I've integrated this into the templating system by creating a function that can display an input form for any object type. It's formating is simple so an addres might look like
line 1 _____ line 2 _____ City _____ State _____ ZIP _____To get around this you can create a function called template::widget::address. If that function exists the form system uses it instead of the default. It might return something like
Line 1 ______ Line 2 ______ City _____, State __ ZIP _____The is also a default validate. Currently if you supply a widget function you must also supply a validate.
Finally there is a function that can take an ns_set of objects and puts them in the database based on the information in the attribute table. It can handle insert and update but currently not delete.
This is all based on the forms part of the templating package which appears to have a lot of functionality but it not well documented.
As for #5 I marked it optional because it's not needed for everyone. In my case it's just as likely the site is accessed by another program and currently the interface of choice appears to be XML.
As far as getting into the base system with the exception of the XML part there is very little code, however for it to be truly useful many base objects might need custom "widgets". The XML part might be more difficult. It's written in PL/SQL and very oracle dependent.
Although a similar facility for editing attributes of any object type would be nice to have, I think the ETP interface should continue to evolve into the best way to edit content_revision objects and their subtypes.
Also I've been thinking about making acs_object_types and acs_attributes acs_objects so I can use the permission system on them. In the above example if I add an approved attribute to the table I could use the permission system to show that attribute to the "content manager" and not the person writting the article.
A by product of this would be the ability to create and manage acs_object_types form a web interface just like any other object.
To revive this thread and to get some clear guidelines from the community.
I'm experimenting with creating acs-objects, but I'm not sure how to use attributes.
At the risk of oversimplifying I concluded the following:
- There is no need to declare attibutes for a new object, since there are no 'core object-methods' that use them.
- The acs_attribute table should be seen as a normal extension table to store:
- a description of a collumn
- columns that are created dynamically when you don't want the original table to change (at the cost of a lot of overhead information in the acs_attribute_values table)
- columns that should be able to store more than one value (in combination with the acs_attribute_values table).
Please any feedback on how to use attributes. If I'm wrong with the statements above, I would like to know whether all columns of an object_value table should be declared as an attribute. I would like to keep it simple.
Personally I think it's valuable to have the metadata available - for instance there's code in the content management system to automatically generate forms, do revision inserts, map widgets to types (to serve as defaults) or attributes (to override the default), etc. The CMS UI is painful but the use of attributes isn't, though it would be nice to be able to describe attributes at a high level rather than painfully define them once in Oracle PL/SQL then Postgres PL/pgSQL.
Bottom line, then, is that the metadata has been used by aD in the past to provide for automatic content management of arbitrary content types and that we should make more use of metadata and work harder to support rapid development.
However the CMS carries its own attributes and other baggage due to its history as a standalone product but that's another issue.
So in my world I'd ditch the attributes values table, multiple valued columns (though we might be able to map those into Oracle and PG arrays in the type table since both offer some support), automatic initialization of attributes by the object creation routine (SQL's "default" works quite well for real columns in real tables), etc. I'd view the attributes mechanism as a provider of metadata in order to speed development, rather than a mechanism to implement a true object-attribute system.
As you can see from the thread here, there are those in the community who really like the full object-attribute model. My view is by no means a consensus view.
If my 'rephrased' summary comes close to what you were trying to say (and inheritance of 'core-attributes', like context-id, are ensured), I would be pleased.
Your words rephrased?........
" There are reasons from the past why attributes are used. However, in the future, I would like to see acs_attributes table being used more consistently for metadata (only); not as an intermediate to store values. (It would be nice to be able to describe attributes at a higher level, than at the PL/(pg)SQL level.) ".
If this could be a guideline, I suspect I should ignore 'table_name' of the acs_attributes table (it isn't used in the standard tarball anyway). Subsequently, I would stick to 'table_name' of the asc_object_types table for all common values and to 'type_extension_table', as an intermediate, to store all subtype specific values.
1. What would be a classic example for storage of data?
This brings me to another observation. 'Table_name' and 'type_extension_table' seem to exist for the purpose of metadata too. I queried the 'user' object in the acs_object_types table and I noticed that the user_preferences, user_profiles and user_portraits tables are not mentioned. Finally, acs_user was mentioned as package_name in that query, but this package is not defined in my package directory.
2. It think I can use any random-named table that references the object_id to store object values. Right?
3.(By the way, would it even be possible to enter more then one table name in the 'table_name' column of acs_object_types?)
Of course these are newbie-questions, but I cannot find an answer elsewhere and these uncertainties don't make life easier. So if you would be so kind to answer again, or someone else, then please.
I think it would be very cool if OACS had a generic facility for creating search/edit/add/delete forms for any object type. As well as the ability to add/delete attributes for these object types. Perhaps even allow the creation of subtypes from an existing parent type.
As a potential application of this, imagine being able to add attributes to the "user" type and having these attributes automagically appear in the site registration and user profile forms. This might also greatly simplify the creation of new packages as well as allow for super-fast prototyping.
I poked around a bit, and it seems that we have bits and pieces of this in the OACS currently (ie, attribute::* for managing attributes, attribute::add_form_elements in particular for generating dynamic forms, define_function_args, ETP has its own attribute manager, etc.). But overall this API and acs_attributes in general seems to be sparingly used.
Barry: you had a lot of great ideas in this thread. You also mentioned that you might release your code. Any news?
Would this be an worthwhile goal for the upcoming 5.0 release?
> facility for creating search/edit/add/delete forms for
> any object type
Just to be extra clear, I meant the auto-generation of forms and code for searching/editing/adding/deleting objects of a given type.
Yes that will be great. Maybe you can show the stuff you did some time ago? Also Tom Jackson I think is doing something similar with his Form builder I think.
Ded's classifieds package does something similar too. Maybe its time to have a standard.
Unfortunately, my package was written before I understood or even appreciated the object system, so it's not integrated at all and therefore of limited value.
But it does store lots of extra meta-data for table columns such as foreign key data (which it uses to generate dropdowns), SQL statements (also for drop-downs), info for including fields in search/edit/add forms, column sort orders, other stuff I can't remember. Perhaps some ideas would apply to the oacs attribute system, especially for the admin UI.
But perhaps, in the end, this idea is of limited value in the world of real applications. But it sure does sound good! =)
I guess. It looked real good from a developer's eyes. Since we aren't able to use it, it does prove our opinion that its a nifty developer idea with little real world application.
Still I think it would be nice. Maybe if the app will write code? Instead of a system/package that does things from you. You basically use it to create some form of template or framework for you. Like converting what you have done to a admin writer package. The code should be bare minimum so the developer will only have to add, not add and subtract code.
So an admin package that runs on a particular engine looks nifty, but a admin package that writes bare code using OACS standard code may have good use?
I have some code but it's not really good for general use. It's built to render forms with more than 100 objects. I tried using ad_form but it was too slow. I do have code for building obects/attributes, validation etc. I have repackaged some of that and would be more than happy to make that available.
I would like to work out what people would like from the object system. After working on the validation package I think it's easy to make it worth while to create objects. Just being able to validate data with ad_page_contract is a big win.
Perhaps we should start a object model requirments thread but the way I see it the requirements would be. (in order of importance)
Web base object builder auto build database objects from acs_objects auto build generic validate routines for all data auto build ad_page_contract validate routines make object_types and attributes acs_objects auto build "form widgets" and ad_form for objects dump code to file search objects make all this subsite awareIt would also be nice to add allow objects to contain other objects but that complicates things. The system I wrote allows this in special cases. The most useful case it just add object_id to acs_datatypes and allow 1 level of nesting. The next thing would be to really add the ablity to have mulitple data for an attribute. The attributes table seems to imply that you can with min_n_values/max_n_values. It would be nice if this worked then you could for example have a contact with a person, 0-5 addresses and 0-5 phone numbers.
Other features that could come latter
Generate XML schema for an object Dump XML data for objects Import XML data for objects Syndicate objects from one acs system to anotherAll of this could be done as an addon module or built into the core. The first set is enough to allow a person with no database abilty (or a lazy programer) to create pages that gather data from forms and search it.
Barry, it sounds like we are working different ends of the same problem. I haven't been that interested in solving the form generation problem, since I seem to always have a lot of fields that should not be available to any/all users. But you can check out my query-writer package. It is due for an upgrade, where I will make a few data model changes and scrap most of the admin ui (I think). I am planning on changing the tcl api so that procs named qw_* will be renamed to qw::*, but the url api will remain unchanged.
The biggest change will be that you should be able to create the pl code for the package with one tcl call, giving the name of the table to base the object on. I already have the function to go through pg and find all attributes, back to acs_objects that would apply to the object. Further api calls could add/subtract/modify the default pl code generation. Another big change will be that a lot of pl code will be replaced to use regular dml code. Updates can use a little pl (an is_object_p function) plus mostly dml, deletes might involve more pl. But updates are the big problem, being very inefficient in pl, where each attribute is updated separately, and then you need a separate function to nullify, or reset an attribute value.
The query-writer also works for non acs_objects as well.
Check out the trace function for attributes here.
I'm also experimenting with a table specification/generation idea that uses a language similar to xml, but far simplified. I figure having a db neutral method of table specification could speed up and regularize table code writing. I like having named constraints for every column constraint, and it is a lot faster do this automatically.
have you seen Apache Torque?
I think auto generating validate routines is more useful (and easier) than forms. As you have noticed not all fields are shown to all users. The way around that is to permssion the attributes. While I think all that would be useful it's not that hard to make a form in the first place.
On the other hand it's a pain to write all the validate routines and it's easy to generate them.
I have code that can build oracle database tables from acs_attributes. If there were something that could import and export attributes then you could load up the attributes and build the tables.