While reading, please keep in consideration I'm still learning Symfony2, as I'm new to it. I'm a bit stuck into this so I haven't done anything yet - in fact, I come to you exactly to get myself lead to the right place.
I have, as my requirements, to enter student data into a form. The issue is that most of the data is already split into several classes with indirect relationships. A Person has one InformationContainer, which in turn has several Roles and InformationUnits (some information units are mandatory only when certain roles are added). In turn, Student is a role and it has several StudentAntecedents (as it can vary yearly), which has a Representative (ManyToOne), which is a Role. Also, InformationUnits can hold several information such as birthplace, ethnicity, etc.
As you can see, this has several classes in it. But I must add Person information, InformationUnit information and StudentAntecedent information (and not all of them) in one form. I'm aware I could just go ahead and use embedded forms but I have the feeling it could break (Person does not associate directly to InformationUnits, for instance). How do I do this?
Thank you beforehand.
Related
I'm developing a page with C5 needing various data to be attached to the user accounts. There are two types of users, having different data. Some of the data is multi dimensional and therefor needs custom DB tables. My question is now if it makes sense to store all data in custom DB tables or to use user attributes for the one dimensional data.
Probably there is no general answer to this, but maybe some pros and cons?
I'm often asking myself where to store data in Concrete5 and would be interested how others decide ...
Yeah. I'd definitely store as user attributes for similar reasons to the one you've already identified (visible, searchable, etc).
concrete5 is extensible, but not super extensible; you can attach data to a user using attributes, but not through some totally custom object / db table that you also expect to, e.g., show up on the user profile page.
Oftentimes in c5 (like any other framework), doing it the Right way (attribute) is more difficult (especially for the first "object", but also for each additional one) than just creating a db table and linking to a user id. But, like in all frameworks, you'll reap benefits down the road that you hadn't even considered. This is in searching, upgradability, and things that might only occur to the guy who takes over development next year.
So, with all that being said, go with attributes. And not just for the one dimensional data. You can configure the attribute controller (and the db schema behind it) to store any data you wish. Look at the Address attribute. This contains multiple fields (though it's still 1D). I think there's an opensource "multi address" attribute out there which stores 1-n addresses as a single attribute. You can do this with an additional linked table, but I've recently gotten lazy with c5 and done no-mysql by dumping json_encode()ed (multi-dimensional) arrays in the "data" field. (In this case, your attribute doesn't even need its own table -- it can use the Default table.) You can then configure the editing interface and also the display value (so, e.g., it just shows a list of each sub-object's Name property). Similarly, you can configure the text that gets indexed for searching purposes.
You asked for pros/cons. Doing this custom will be quicker and more straightforward. Extending an attribute, especially to create something complex, isn't super simple, and there isn't a lot of good documentation. Also, the attribute-editing UI (on the user dashboard page) is a bit kludgy. Yes, you get to "design" whatever you want within the "table cell", but you're still limited to making the admin click on the attribute name, using your editing interface within the cell, and then (ideally) clicking on the little disk icon. (Creating a javascript dialog might solve some issues here.)
I've been using this site as a great resource since I started at school - but I've never had a problem this specific before and I was hoping for a bit of help. I was never the best when it came to figuring out database structures, and I've been tasked with creating a PHP/MySQL test engine with some rather specific specifications.
So you can better understand what I'm going for here - I am trying to take into account the following:
Administrator and student login are required, and provide different levels of access.
An administrator should be able to build one or more tests and assign it to one or more students.
For each question an administrator builds within a test, the administrator should be able to assign a point value.
A test should be able to present one or more questions.
Your application should support three basic questions types: true/false, multiple choice and fill in the blank.
Final results will display an overall score, as well as a student’s response to each question.
A student should be able to see final results for only test they have access to.
An administrator should see results for tests from multiple students.
Students are not allowed not retake the same test.
Mostly, I am trying to deal with the basic structure. I had five tables at the start, I condensed the Question/Answer section into one table - and excuse my poor attempt at switching around the relationships here, because I've had them 20 different ways it feels:
Am I on the right track? Any suggestions?
A good rule of thumb with database design in N-1. For all tables that have relationships, you should have N-1 relationships (where N is the number of tables). Tables with circular references are a no-no. Putting as the security components and just looking at test/questsion/answers, you want a design that has Some basic objects:
Admin (or teacher) table
Test table
Student Table
Question Table
You didn't mention it in your question, but if you want each test to be associated with a class that the teacher teaches, you will need that as well. With those four, or five, tables you should be able to create your relationships. Hint: Most of these relationships are many-to-many and, as such, will need an XRef table to resolve this. Post back what you do with this and we can look at what's next.
I'm currently creating my own PHP mvc for a site that I run so that it will include just the code needed yo be as light and fast as possible.
The site has quite a large range of functions and user features so working out which actions go where in which models controlled by which controllers is starting to get quite complex.
Example
Say I have the following member features
Favourites
Friends
History
Each of those can be controlled by the membercontroller but then my question is whether to have them all inside one model or a model for each.
Each of those three has sub many actions such as:
Add to favourites
Remove favourites
Show favourites
Add to history
Remove history
Show history
Add as friend
Remove friend
Message friend
...etc
At the moment I'm thinking a model for each (favourite, friends, history) is probably the best way, but can it get to a point where you have too many models?
At the moment the whole site has 6 controllers, 17 models and 25 views
Yes you can technically have too many models, there is a limit (as always) of how many classes can exist in PHP. But it's pretty large, so keep on going. You can not only have many but also different kind of models at once. So keep on going, don't restrain your coding by thinking there might be a limit you don't see so far.
So not the count of files, but how nicely written your code is, e.g. is everything grouped properly that belongs together? See as well Domain Model.
I suggest you let ModelController deal with actions that somehow modify Model.
I.e. FavoritesController deals with adding, removing and showing favorites (stored on FavoritesModel). Keeps your controllers lean/slim, is a lot easier to test (less methods) and keeps logical app parts together.
Also, you could divide the application into smaller apps that deal each with:
Auth/Login
Social/Sharing
add/read/show articles (main app)
In such scenarios there is no "right" answer, so all I can give you is my own interpretation. I would use a service to do bind one or more models together. So, a User service would use the User model and the Favourite model to manipulate and display user favourites.
I have been tasked with creating an application that allows administrators to alter the content of the user input form (i.e. add arbitrary fields) - the contents of which get stored in a database. Think Modx/Wordpress/Expression Engine template variables.
The approach I've been looking at is implementing concrete tables where the specification is consistent (i.e. user profiles, user content etc) and some generic field data tables (i.e. text, boolean) to store non-specific values. Forms (and model fields) would be generated by first querying the tables and retrieving the relevant columns - although I've yet to think about how I would setup validation.
I've taken a look at this problem, and it seems to be indicating an EAV type approach - which, from my brief research - looks like it could be a greater burden than the blessings it's flexibility would bring.
I've read a couple of posts here, however, which suggest this is a dangerous route:
How to design a generic database whose layout may change over time?
Dynamic Database Schema
I'd appreciate some advice on this matter if anyone has some to give
regards
SWK
I created a very large EVA database years ago (PHP w/ PostgreSQL). It turned out great, but it was large project ($$$). All the forms were completely dynamic, with form/field versioning, publishing workflows, matching dynamic reporting, etc.
EVA basics are easy enough. Getting data in is not the hard part. But form versioning and reporting....you can spend years getting it right.
If I was doing it again today, I would research using one of the newer NoSQL solutions ( http://en.wikipedia.org/wiki/NoSQL#Document_store ). I'd thing about creating a DTO style class that could be passed to a form generator. "Modifying" the form, would actually be modifying the DTO. Then I would persist that DTO into a document/object database.
Also, as you are building your alpha solution, think of how to solve test cases that encompass versioning and reporting needs.
Here is an example of what I mean: A simple "Ask Question form".
Original (version 1): has First,Last,Question
Add email field(Version 2): First,Last,Email,Question
Somebody changes their mind about email: (version 3): First,Last,Question
New marketing guy comes in and changes it: (version 4): Full Name,Email,Question
Now, you need to generate a report (csv). Things get tricky. How do you do it?
We solved this problem with field level versioning with references to their previous versions. Plus the reporting system required the end user to assemble the definition of the report data sources before running. (binding report fields to data fields, etc).
However with the document DB's I'd imagine you can do it differently. I believe the new DB's like CouchDB (others??) have mechanism built in for handling these issues.
Good luck!!
When developing user profiles in my last webapp, I've chosen Key/Value table approach. Here's how my DB design looks:
Users table with fixed columns:
id
login
name
regdate
Users table linked with Profiles table (User HasMany Profile).
Profiles table with different data:
user_id
field
value
This way user can add any additional field to his profile. For example:
user_id = 1
field = 'Facebook'
value = 'http://facebook.com/...'
and
user_id = 1
field = 'Stackoverflow'
value = 'http://stackoverflow.com/user/...'
and so on..
Depending on your needs, it might not be worth even raising the form fields to the "DB fields" level. You could instead serialize these fields in (what is essentially a) dynamic blob and store it in the DB. This is NOT recommended if you have folks who need to query these dynamic fields outside of your app (i.e., the DB design is part of a larger public contract with integrated systems), but if you're just using the app to simply to persist these dynamic fields or if any aggregation/search capabilities within the fields are minor, then I would consider it (esp given CPU capabilities these days). I have used the pattern many times and I have - thus far - never had to refactor. (however, I can understand a case where you might need to).
Currently, I am working on restructuring an existing code base. I'm new to php frameworks, but I do know in general how MVC works.
Right now, there is one controller file, one model file, and thirty view files.
Should every model correspond to a table?
Should every view correspond to an html page?
What about the controller? How can I break this thousand line monster into more organized code.
Thanks.
Should every model correspond to a table?
No. A model is often constructed from data from multiple sources. Don't think in terms of tying it to your physical database structure even though there will probably end up being lots of similarity.
Should every view correspond to an html page?
Not to sound trite, but every view should correspond to a view. I'm not sure exactly what you mean by a "page".
Perhaps an example would be useful. Imagine a user registration page. The model is User and might contain fields such as:
Title
Given names
Surname
Date of Birth
Username
Address(es)
Email address
Phone number(s)
etc
Now, that data may be in multiple tables. For example: Party, Person, Contact and Address.
There will probably be several views:
About page
Form page (used for new registration and possibly editing details as well as errors);
Success page;
Failure page.
Typically all of this will be handled by a single controller as all the processes are inter-related.
Every model should correspond to a logical data object - which should generally predominantly be stored in one table (often with foreign keys into other tables, since models generally need to reference other models).
Every view should correspond to a logical way of viewing your data (e.g. on stackoverflow, there is hopefully a view for the list of badges pages, a view for the list of tags pages etc).
Every controller should correspond to a logical grouping of views, which should not be too big (where too big is the line where the file is becoming unmanageable - if you've got 30 views, you can hopefully find a logical way to group them into say 3 controllers).
What about the controller? How can I
break this thousand line monster into
more organized code.
Have a look at CakePHP framework and how it solves the problem of large models, controllers, and numerous views. I find it quite elegant. Complex models can have behaviours. Large controllers can be broken into components. And numerous views are grouped with layouts, while having common bits separated into elements. It might sound complicated and scary at first, but once you try to use it, it really falls into place.
Should every model correspond to a
table?
It doesn't have to but it often will depending on the complexity of your business logic.
Since you're refactoring an existing application, think about how the model is used by the other layers. In MVC, the model is at the bottom of the dependency stack.
How will the view access the model? How will the controller modify it? How will the model be populated?
Should every view correspond to an
html page?
Again, it doesn't have to but it often will.
What about the controller? How can I
break this thousand line monster into
more organized code.
A common strategy is using the front controller pattern. The front controller deals with HTTP requests, application initialisation and site-wide logic (just as your thousand line monster is currently doing) - but then it delegates to more specialised controllers.
These specialised controllers could be grouped by the models it uses, site page structure, or anything else that seems logical. They then interact with the model and select a view to display.
Finally, +1 to frameworks as Leonid suggested. Even if you don't end up using one, there are some great implementations of controller patterns out there.
Hope that helps.