lacking a fellow programmer to talk over the right approach for my problem, I decided to ask you. What is your preferred approach of mapping dictionary tables to a model in MVC paradigm, regardless of the MVC framework / environment you are using?
My problem is I have a couple of database tables that only serve as dictionaries and are related to other tables as foreign keys. A good example would be a table request having a status_id where statuses are kept in a separate status table.
Now, the latter table needs to be mapped to a model on the code-side of the application. I can either:
Define all the statuses as constants so they can be referenced in the code without poking those dreaded 'magic numbers' here and there. However, any change to the dictionary (database-side) would require a code modification.
Omit the `status` table at all and just define meaningful constant to be used across the code. Pros: one place to rule them all. Cons: all changes require diving into the code, now the database features 'magic numbers' not really being foreign keys
Try to translate statuses into the model automagically, adding a field like 'const_name' to the 'statuses' table and them creating the constants on the fly while loading the model. This one seems to have the most sense for me.
Would you mind to share your usual approach to this issue?
Best,
Bartek
If it's just going to be a set of constants that are contained in the database instead of code, you could have a static class load the status constants for everyone else to use. That way there's no duplication between db and code, and no magic numbers.
edit: since it's a static class, you could have it lazy load the constants. Don't hit the database until the first time someone asks for a status value.
I'd say if you going to change it often it's better to go with table. Otherwise static class is fine (for example no point having table to store sex, or list of states).
Related
I've modeled the following UML for the database of our website (uni project):
However, I can't seem to find how to convert to SQL the generalization case between Post, Story and Comment. My teacher suggested to use the same table, but I think that limits me if I want to add more features, like tags for stories. Right now I already have two extra relations: a post can have several child comments, and a story belongs to a specific channel.
Should I follow my teacher's suggestion? Or should I use 3 classes?
Since your class hierarchy has only two subclasses that come with only 3 additional properties (title, channel and post), you should use the Single Table Inheritance approach. Even when you may add a few more properties/methods later on, this will be the best choice, since implementing your class hierarchy with multiple tables would imply a much greater effort/overhead.
You can read more about this choice in the section Representing class hierarchies with SQL database tables (of a tutoral on handling class hierarchies in a JavaScript front-end web app authored by me).
As always it depends. Having a single table has the advantage of accessing related post info in a simple query and just looking at a flag inside the column telling what kind of object you're dealing with. Having separate tables is a more "academic" way of solving it since you (as you noticed) have object information separated.
I'd probably go with the single table approach in this case. But - YMMV - you can as well stick to your 3 table approach. There might come other opinions here. Just wait a few days to decide :-)
I was given this project to work on with absolutely no documentation or contact developer. I noticed in the database dump that they are storing what looks like PHP Namespaces for Eloquent models in a couple tables. For example an address table has a string column named "object_type" with the value always being "App\Entities\Client". I searched through the whole project for the PHP code that would use this value. Hopefully to give me insight to it's purpose. Not to my surprise, the project never uses this value. I just see it hard-coding these values upon insert into the DB.
My question is, is this some sort of Database and/or ORM modeling design practice? If so, could you explain how this could be used in a simple practical sense?
Maybe this was some concept the developer had and it never evolved. It's interesting idea but, the idea of joining through MySQL on a string conditional sounds like torture.
Sounds like Laravel polymorphic relationships:
Custom Polymorphic Types.
By default, Laravel will use the fully qualified class name to store the type of the related model.
And, yes, this is a valid modeling technique, though purists rightly argue this technique abuses normal form.
I am not sure what the developers where thinking.
But imagining we are in a forum with thread and replies to each thread. We maybe want to have a Favourites table where we can save replies and threads.
A way to do it would be to have a column in the favourites table called "object_type" (just to use the same term you have in your case) and then when we save an object into the database with eloquent we can use:
$favourite->object_type = get_class($thread); //or get_class($reply) in case we want a reply
$favourite->save();
This way will save the namespace of that class into the database. But laravel will recognise it when we get it from the database.
Hope this cold be helpful.
I was wondering how does you guys write your classes when they need tables in the database to function or some other things to do before it functions?
Do you use a method to insert the tables in the database or do you write the class to require some columns in a table which can be define at some settings variable?
Whilst the answer to this question is a matter of opinion, I would generally create them in the class constructor (checking whether they exist first or not), however I would allow the user to specify their own names and prefixes to avoid clashes and data loss within their database.
The reason being is that you have total control over how the tables are constructed as opposed to trusting the user to generate them correctly.
This is assuming your class will be used by other people, if it is solely for your own use it is safe enough to assume you are able to build the tables yourself and could remove that overhead from the class.
It also depends what your class is for, if it is a plugin then you should definitely create these for the user so they don't have to touch the underlying code, following any of the database naming conventions of the system your plugin is integrating with.
This is just my personal style and is by no means a standard or necessarily the optimum way.
This isn't much of an issue with MySQL per-se.
The Full Story
I'm writing a very small PHP framework. It isn't like existing frameworks where they force you to use a certain methodology. It isn't either like a CMS framework. Trust me, I've seen Zend framework and I've used CMSes like Joomla and WordPress extensively, none of them come close to what I'm doing.
Introducing The Issues
I'm writing the Database abstraction part. You get class methods like ::table_exists() etc.
It is designed in a way that people can easily add different database classes and use them instead (eg; mysql, mssql, oracle, flatfile...).
They simply need to write a class which satisfies a base abstract classes'.
The Real Issue
I'm writing the functionality for ::table_create(), but have one main problem: MySQL doesn't like empty tables (ie, without a column).
I have several proposed fixes:
For each new table, create a commonly used column, such as 'id' (type=INT)
For each new table, create a temp column which doesn't use any space as much as possible (perhaps a boolean column?)
Somehow delay table creation until at least one column can be created
This approach is most certainly new, and I'd like to here some unbiased comments about it (anything on the lines of "but no one does it that way" won't do).
Well I would either go with option 1), Adding a generic ID column, which you might find you need anyway, or with option 3) Delaying the table creation. I'm assume after they call ::table_create() they will be calling table_add_col(), etc. So just delay creation until there is at least one column, OR until they actually try and use the table for the first time.
Your proposed fixes look quite good. But I would recommen them in a diffrent order. If you are able to delay the creation, tht's probably the best. My second favorite would be to have a table with only an ID, although you might be delete this column, if you want to create a many-to-many relations table with two foreign keys only.
last of your points.
its really very strange what you are doing here. creating tables on the fly? dynamically or something?
well... whatever you are trying to accomplish. you should have a look at document/object oriented databases like couchdb http://couchdb.apache.org/ ! you can create a document and dynamically add whatever fields you want. those are the closest thing to your "columns"
but as you like it...
your first attempt is ugly because it might lead to conflicts.
the second attempt is clumsy. but if you do so create a col with uniqueprefix_random so you can delete it afterwards.
but its well... i dunno what to say about that.
theird approach seems the only senseful!
I've been reading several articles on MVC and had a few questions I was hoping someone could possibly assist me in answering.
Firstly if MODEL is a representation of the data and a means in which to manipulate that data, then a Data Access Object (DAO) with a certain level of abstraction using a common interface should be sufficient for most task should it not?
To further elaborate on this point, say most of my development is done with MySQL as the underlying storage mechanism for my data, if I avoided vendor specific functions -- (i.e. UNIX_TIMESTAMP) -- in the construction of my SQL statements and used a abstract DB object that has a common interface moving between MySQL and maybe PostgreSQL, or MySQL and SQLite should be a simple process.
Here's what I'm getting at some task, are handled by a single CONTROLLER -- (i.e. UserRegistration) and rather that creating a MODEL for that task, I can get an instance of the db object -- (i.e. DB::getInstance()) -- then make the necessary db calls to INSERT a new user. Why with such a simple task would I create a new MODEL?
In some of the examples I've seen a MODEL is created, and within that MODEL there's a SELECT statement that fetches x number of orders from the order table and returns an array. Why do this, if in your CONTROLLER your creating another loop to iterate over that array and assign it to the VIEW; ex. 1?
ex. 1: foreach ($list as $order) { $this->view->set('order', $order); }
I guess one could modify the return so something like this is possibly; ex. 2.
ex. 2: while ($order = $this->model->getOrders(10)) { $this->view->set('order', $order); }
I guess my argument is that why create a model when you can simply make the necessary db calls from within your CONTROLLER, assuming your using a DB object with common interface to access your data, as I suspect most of websites are using. Yes I don't expect this is practical for all task, but again when most of what's being done is simple enough to not necessarily warrant a separate MODEL.
As it stands right now a user makes a request 'www.mysite.com/Controller/action/args1/args2', the front controller (I call it router) passes off to Controller (class) and within that controller a certain action (method) is called and from there the appropriate VIEW is created and then output.
So I guess you're wondering whether the added complexity of a model layer -on top- of a Database Access Object is the way you want to go. In my experience, simplicity trumps any other concern, so I would suggest that if you see a clear situation where it's simpler to completely go without a Model and have the data access occur in the equivalent of a controller, then you should go with that.
However, there are still other potential benefits to having an MVC separation:
No SQL at all in the controller: Maybe you decide to gather your data from a source other than a database (an array in the session? A mock object for testing? a file? just something else), or your database schema changes and you have to look for all the places that your code has to change, you could look through just the models.
Seperation of skillsets: Maybe someone on your team is great at complex SQL queries, but not great at dealing with the php side. Then the more separated the code is, the more people can play to their strengths (even more so when it comes to the html/css/javascript side of things).
Conceptual object that represents a block of data: As Steven said, there's a difference in the benefits you get from being database agnostic (so you can switch between mysql and postgresql if need be) and being schema agnostic (so you have an object full of data that fits together well, even if it came from different relational tables). When you have a model that represents a good block of data, you should be able to reuse that model in more than one place (e.g. a person model could be used in logins and when displaying a personnel list).
I certainly think that the ideals of separation of the tasks of MVC are very useful. But over time I've come to think that alternate styles, like keeping that MVC-like separation with a functional programming style, may be easier to deal with in php than a full blown OOP MVC system.
I found this great article that addressed most of my questions. In case anyone else had similar questions or is interested in reading this article. You can find it here http://blog.astrumfutura.com/archives/373-The-M-in-MVC-Why-Models-are-Misunderstood-and-Unappreciated.html.
The idea behind MVC is to have a clean separation between your logic. So your view is just your output, and your controller is a way of interacting with your models and using your models to get the necessary data to give to the necessary views. But all the work of actually getting data will go on your model.
If you think of your User model as an actual person and not a piece of data. If you want to know that persons name is it easier to call up a central office on the phone (the database) and request the name or to just ask the person, "what is your name?" That's one of the ideas behind the model. In a most simplistic way you can view your models as real living things and the methods you attach to them allow your controllers to ask those living things a series of questions (IE - can you view this page? are you logged in? what type of image are you? are you published? when were you last modified?). Your controller should be dumb and your model should be smart.
The other idea is to keep your SQL work in one central location, in this case your models. So that you don't have errant SQL floating around your controllers and (worst case scenario) your views.