How to setup cross app entity relationships in 2sxc - dotnetnuke

I am new to 2sxc and am trying to build a relatively complex website using this module as base for developing the data modelling.
My site consists of lots of different Apps (in my view), like news, events, people, workgroups, etc.
My question is how should I address the relationships between entities:
on one hand, I know that I can create relationships if all entities belong to the same APP. But this does not promotes reusing existing apps and makes a single app more complex.
on the other hand, creating different apps, would promote reusability but has the additional complexity of cross app entity relations (if that is even possible?).
Are there any recomendations on how to tackle these issues and how to setup a cross app relation?
Ex: WorkingGroups has a relation to people (one to many)
Both Events and News share a relation to Categories (tags)

An App is a self-contained unit which can be exported/imported and should still work. So if items in an app relate to each other, that is how it's meant to be.
If you create cross-app relationships (this is possible) then you lose integrity checks and similar.
So if you have complex issues tightly related it should be in one app.
If you have multiple apps which just use another app for additional lookup, that is possible
EG: Let's say you have a people-app which describes the people, and you want to have other apps (like news) which mention a person - and the goal would be to be able to click on that person to get that profile or similar, this is how you would do it:
Create the people app
Create the news app
In the people-app, make sure you have a unique ID for a person. I wouldn't use the data-id (a GUID) but rather a person code (like DM for Daniel Mettler) or similar.
In the news-app, also create a person-id field. For simplicity, let's say it's just a text-dropdown. You could also create a data-dropdown which gets data from the other app, but that's advanced - so do this later. For now, make a dropdown and pre-fill the IDs of known people.
Now you can create all the views etc. Make sure you add some null-checks and similar so the code doesn't break if it doesn't find the ID in the other app.

Related

How to structure an app that has several versions per customer?

Recently, the company I work for has given me the task of unifying 2 angularjs apps into one.
While I'm trying to wrap my head around it, here are the details:
- The two apps share quite a bit of common logic
- One of the apps (main one) is public facing, the other is made for a specific customer.
- Each app currently uses it's own database, this is because the customer's app is more complex and requires more data.
- Some of the common logic of the public app is being overwritten by the customer app due to the nature of it.
As an example, the login page is pretty simple in "public" but would have an extra layer of validating a registration code in "customer" and fetching the right data from the DB for this code.
I am trying to figure out how to I unify them both into 1 app, while having the ability to throttle between app modes or something similar
There is a way to tackle this using DDD (Domain Driven Design). Make a clear cut of the domain for both apps. For instance, if you encounter 2 user models in 2 different domains, as this is the case, you want to differentiate between the two of them.
Where this won't give you a framework to structure your application, it will provide a clear mindset on how to structure your application and correctly naming and identifying your contexts, domain and models.
Having clear domains should make a clear cut on which models can access X resources in the database.
Throttling is also an option, but I would only do it this way if I wouldn't have to maintain one of the versions. If the development branches only towards one, deprecating the other, then it is a reasonable solution, but maintaining 2 development branches this way is very painful.

App Engine entity groups: grouping all of a user's data vs avoiding them as long as possible

I'm working on a web application that allows users to create simple websites and publish them on a static web host, and I have problems deciding if and how I should use ancestors in the gray area between necessary and avoidable.
The model is rather simple: currently every User has one or more Website entities. The Website entities store all the basic information about a website, plus it's nested navigation menu that refers to Page entities (the navigation tree is stored as a JSON property). The Page entity types are based on a PolyModel, and there are several page types that behave differently (There's a GalleryPage, for example).
There are no entity groups (or rather, no entities with ancestors) as of yet, and I'll only need a couple of transactions. When updating a Page's name, for example, I have to update it in the Page entity itself as well as in the navigation tree on the Website entity.
I think I understand how entity groups work and the basic implications of using them, but I have trouble deciding on the "best" way to structure my data in the absence of strong reasons for either approach. I could:
Go entirely without ancestors on my entities. As far as I understand I can still use cross-group transactions as long as I get the entities by key and don't need more than 5 within the transaction. The downside is that I'd depend on the XG transactions and there might come a point where I can't ninja my way around using ancestor queries anymore (and then it might be too late).
Make the user object the parent of all his Website's, Page's and other data. This would give the user a strongly consistent view of all of his data, allow me to use transactions whenever I add a feature that would need them, but limits the sustained writes to 1-5/sec. But, as a user will only ever be updating his own data, this might actually work and behave just the same for 1000 users as it will for 1.
Try to use even smaller entity groups (like seperating the navigation from the Website and making that the parent of the Website's Pages). But I'm not quite sure if there's much benefit to this, because most of the editing happens on Pages anyway.
So I guess the real question is: how do you decide when to use ancestor relationships on App Engine when there's no obvious reason for or against them? Would you go for the convenience of strongly consistent queries and being able to use transactions freely while adding features later, or would you avoid them at all costs until there's a very obvious reason for them, even if might limit my ability to do transactions later?
I read the related documentation, read the chapter on transactions in "Programming App Engine", looked at quite a few of the Google I/O videos, but I still find it hard to make that decision.

CakePHP - where to put service logic

I am Java programmer who tries to investigate CakePHP - currently I have problem with application structure/design. I could not understand where to put core logic of application.
When I am developing in JavaEE, common approach looks like following:
Model classes are simple beans which represent data entities (products, people etc) - mostly like data structures with getters/setters;
Controller classes are simple enough classes which aggregate necessary data and inject them into dedicated View template which is then sent to user;
DAO (DataAccessObject) or Repository classes are ones which can load and store entities into database;
Service classes are usually singletons which contains certain business-logic methods - these are called by controllers, by other services or by scheduled actions, on the other hand they themselves call DAO / Repository methods to fetch or modify data.
For example if I have entities Person, Product and Order, when user selects some product and clicks "put it into my cart/basket" new Order for this Person should be created and this Product should be added to this Order (we may check that Person is not bad debtor and that Product is present at store etc.) - all this work is performed in methods of OrderService called by some controller.
Usually some kind of IOC (Inversion of Control) is used so that all services and controllers have links to necessary services etc.
Now I am slightly bewildered about how this all is done in CakePHP. Where should I put this business-logic etc. ?
In CakePHP the model layer is made up from collection of active record instances, called AppModel. They combine the storage-related logic (that you would usually put in DAOs and/or Repositories) with business logic (what usually went into your "models").
Any other domain related logic (from your Service) becomes part of controller.
If you want to know, how you are supposed to implement domain business logic in CakePHP, just look up articles which praise active record pattern.
Personal opinion
CakePHP and CodeIgniter are two of the worst frameworks in PHP. They are filled with bad practices.
Actually, if you were doing correct-ish MVC, then model layer would contain all of the business logic and everything that is related to it. Model layer is made of DAOs, Repositories, Domain Objects (what you call "models") and Services.
While your descriptions of Java-based code indicates, that you are kinda moving in that direction, CakePHP is not even remotely close to it.
Then again, it might be that my understanding of MVC is just wrong.
The controllers should only contain logic relevant for the whole thing being a web application. Your business logic belongs into the models. I think it is one of the basic mistakes that you find in many cakePHP applications, that to much logic is put into the controllers, which actually belongs into the models.
In CakePHP. the "M" is just a bunch of Data Models instead of Domain Models.
In my opinion. CakePHP is made for RAD development. It is not a good fit for enterprise applications.
My opinion though.

At What Point Does a Form Lose its "Model-ness" and Become a Document?

I have been thinking and learning a lot about forms lately trying to add advanced extensions to the Spree ECommerce Platform: Subscriptions, Events, Donations, and all kinds of Surveys.
Every example I have ever encountered (in blogs, in the docs, in screencasts, in source code, etc.) make forms out of Models, but they never go to anything semi-structured or unstructured (or just really dynamic). So you have forms like:
Contact Form (User Model, maybe divided into an Address Model too)
Registration Form (User Model, Account Model, Address Model, etc.)
Blog Post Form (Post Model, Tag Model, etc.)
Checkout Form (Shipping Model, Order Model, LineItem Model, etc.)
All of those make perfect sense: They are the culmination of 10's of thousands, millions even, of man hours. Tons of people have slowly abstracted those things down into nearly universal "models" that could be saved into a database table. So now we all create models for them and make database tables for them.
But there are so many other things that can't be boiled down to those specific models. Things like a survey for a specific event, with form fields such as:
Are you Pregnant?
How many kids do you have?
Have you ever been sick?
What's your fastest mile?
If we started to save those things to the database in tables, we would have 100s and 1000s of database tables, one for each set of questions, or "survey".
So my thinking is, there's got to be some point at which you stop creating specific models like the "Post" and the "Order" and start just making a "Form" or "Survey" model (Form ~ Survey ~ Questionnaire to some degree).
Everything would be boiled down to these few models:
Survey
Question
Answer
ResponseSet (answers to questions in survey)
Response (specific response in response set)
And from those you could create any type of "Form" you wanted.
So my question is basically: When do you, in the most practical, day-to-day client projects, stop making forms with a bunch of models in them (a "Checkout" form is a form for the "Order" basically in Spree, but that easily requires 10 database models), and just start using Question/Answer or Field/Input or Key/Value? Practically?
I'm just looking for something like "when we built our online tutoring system, we didn't end up creating a bunch of SomeTutorialModel objects which extend TutorialModel, because that would've added too many tables to our database. Instead, we just used the Surveyor gem". Something along those lines :).
There's not much out there on this semi-structured type of data, but lots when you can boil it down to something super concrete.
It seems that if you used a Document Database, like CouchDB, you'd end up being able to create all kinds of Model objects in ruby for example, and could get them out with some clever view tricks. But with MySQL and the-like, it seems insane.
Your question is quite broad, so I will instead of giving direct answers mention these points:
1.) models often reflect the target (core) domain of the application, so the boundary between key/value and model is about the domain
2.) AFAIK e.g. Google uses relational databases even to store key/value data, so they can store everything as using document database
3.) all your questions are basically about modeling and abstraction, which is hard to explain shortly or in general

Why not construct UI based on DB schema?

People seem to avoid building user interfaces that pull their information (names, field types, etc. as well as relationships) from a database; they instead hard-code forms (and tables, etc.) that have pretty much the same data names and types and things.
Am I making sense?
For instance, imagine an emumerated field in MySQL: why not just have the UI construct a drop-down list whenever it encounters an ENUM? Why put the same values in both the database and the code?
Perhaps I'm just missing something; perhaps there are projects out there that do this — sort of super-crud interfaces that can be pointed at any database and from it build a fully-functional relationally-aware user interface. Are there?
I'm possibly not quite conforming to the stackoverflow norms with this question; I shall summarise:
Can you please tell me of a project that constructs its user interface (solely) from analysis of the database schema?
Why is this not a common way to do it — surely it is good to only define data structure in one place (i.e. the database)?
Thank you, and may joyous code-love rain upon your IDE.
I'd like to point out that, last time I checked, .NET and Qt (and probably other environments) make it possible to use "database-aware widgets" (sometimes shortened to just data-aware widgets), which is probably the best pragmatic solution available. What I mean by data-aware widgets is that the widgets themselves know that they're linked directly to database fields, so you would have a combobox that knows that it's backed by an enum and fetches the possible values directly from the database at runtime, just like you suggested.
This is a really neat utility, and used well, it probably won't hurt anything. It still requires that you spend some time laying out widgets manually on a form, but then if you update the database to add a new value to that enum, you don't have to rebuild your app to see it show up in the UI.
But the reason most usability experts will cringe when they hear your question is because programmers tend to think that, well, why not just generate the entire UI, form layout and everything, from the database? And this is where it starts to get really nasty, really fast.
Let's say you have a simple Person table, with first_name, last_name, email_address, street_address, city, state, zip, and phone_number. You want to automatically generate a UI based on these fields. How do you sort the fields? I mean, ideally, first name and last name should be right next to one another. And it would look very silly if you had city and state before street address. So you have to add a new column to the table to specify sort order, if you go with the quickest method, or a new table to specify each field's order index to their field ID.
What if you want to group parts of the information separately? Then you have to add more UI-specific cruft into your database layout (to do this generically, you'll need a new table specifying which UI fields belong to which UI groupboxes). So you've only solved two problems and already your database layout has gotten twice as ugly, plus now instead of a simple O(1) layout operation when you load the UI, you've gotta do several database queries to find out what fields exist and dynamically lay them out while applying the correct widget order... and we haven't even dealt with sizing (should every field be the maximum size to fit its possible contents, or should all text fields be the same width? Wouldn't it be nice if you could say that some text fields should be one width and height, and some should be another combination? etc), or text justification, or formatting, or any other really common elementary usability requirements that will require further sacrifices from the clarity and simplicity of your database schema.
Most visual database editors. phpMyAdmin for instance.
Because the database structure isn't always a very good logical structure for a user to be using, especially in the case of databases that have been denormalised on purpose for efficiency reasons.
Yup, this route has already been traveled.
Simply pointing at a database will create an oversimplified UI, not giving much more than the CRUD of an Access UI. That's why Naked Objects (I'm one of its committers) builds its metamodel from a pojo domain model. This allows the UI to expose any public methods as menus ... we call this "behaviourally complete".
Per the comment about the UI not being suitable for end-users, I have two points:
distinguish between power users vs casual users. Most internal apps are for the former (we use Alan Coopers' term of a "sovereign application" for this), who understand the domain and don't want fancy UI stuff getting in the way. Most external apps, eg public web sites, are for the latter.
for the latter, there's nothing to prevent the autogenerated UI of a tool like Naked Objects being replaced with a custom or semi-customized viewer. One such viewer is Scimpi, I'm also working on an Eclipse RCP viewer that'll expose extension points. But even here, the auto gen UI is still very valuable for the development team and business analysts for exploration and prototyping.
Hope some of the above has piqued your interest. If you want more, google around, or you might want to check out my book on domain-driven design and NO, at pragprag.com.
HTH
Dan
List of projects that implement this idea.
.NET
dotObjects
Naked Objects
TrueView
Java
Domain Object Explorer
JMatter
Naked Objects
Sanssouci
Trails
Lablz
C++
Typical Objects
Specifically to your second question: Alot of it really depends on your data model. Some are very complicated and would lead to un-intuitive user interfaces. Perhaps for simply CRUD based systems, having your UI be a front end to the database would be preferable. In that case, I think that some of these tools would be great. However, for some more complicated systems where some db data needs to be hidden from the users, it would be better if you UI didn't mirror the db schema.
Microsoft Access has used this model for years - the database and UI development are very closely tied. You can auto-generate a form directly from a table definition with smart defaults and search built in. The model works well for developing applications with few concurrent users such as custom applications for small businesses where the amount of data stored is small.
If you are scaling to larger relational DBs with a number of concurrent users, or large databases then reliability and performance become more important, and separately constructed UI and databases make more sense. When more users are involved they often have different requirements so decoupling the UI from the DB schema makes it more efficient to develop.
Just a note on Java "projects that implement this idea" - tynamo is the new version of Trails framework
There are many systems that build an interface for you to edit stuff directly from table information. End-user interfaces, however, must be tweaked a little bit. You may not want to reveal to the user every field in your table.
Frameworks that make good use of the MVC design pattern can let you do all kinds of things with your models, which are the preferred way to build new systems (rather than creating database tables directly).
To answer your questions specifically:
django allows you to construct forms (and a complete admin CMS) out of models.
It is a common thing to do.
Naked Objects is about one step removed from this. They base the UI on an object model, and then persist the object model.
I think you are forgetting to consider the user in your design process if you are thinking like that. Bad mistake. Users don't like it when the interface changes, they would especially not like it if it changed frequently as they then wouldn't know what to do. Further, if you generate your UI on the fly based on the database structure, then what order would the objects be in? UIs need to have objects in an order that makes sense to the users not the database designers.
Further in a well-designed database there are fields that are not meant for the users to see. Things like numeric keys, insert date, last updated etc. You don't want to automatically expose these to the users and you certainly don't want them to have the ability to mess with the data in such fields.
Finally, if you don't think about the functionality of the page, then you aren't doing your job. A UI needs to be more than just a list of fileds that can be edited. You need to have constraints on who can see what, checks of the data before inserting to the database, business rules that need to be applied. You can't just autogenerate a lot of this (and you shouldn't even if you could!). Design needs thought and care.
Now as to drop down lists, of course you can generate them from the database and not the code, in fact it is the better choice. Just make the query the source for your particular object, not a list generated in code.
You can do it with the help of this cool tool from a developer in Philippines, it is called COBALT. You can download it here.

Resources