Datamapper (Overzealous Edition), Codeigniter and Has Many Clarification - php

Firstly, I would like to just it out there that I am an ORM noob. I've never used an ORM in my life and have reached a point in my day-to-day developing that I need to do some crazy advanced relationships that I believe Datamapper Overzealous Edition can help me with as I am using Codeigniter.
In my database I have the following tables;
users
projects
clients
tasks
Here is my desired relationships between the tables;
A user can belong to many projects.
A project can have multiple tasks, but can only have one client.
A client can have many users and can have many projects
A task can only have one project
I have attempted to set-up my models in the models directory as it says in the documentation the model name without the s on the end, so for users I have a user.php model and so on.
I know the documentation is great, but I just can't seem to understand it properly even though it is obviously very easy. I know you instantiate the model by going for example $u = new User(); inside of your controller, but my question is setting up the relationships inside of the models.
How do I set out my models to have the above relationships so for example when I fetch a task I can see what project it belongs to and a whole heap of information from its associated database tables.
I noticed that in the documentation you use the following inside of the projects model which should tell it that it can have more than one task for a project; var $has_many = array('task')
Is that all there is to it? Is it as simple as defining the $has_many and $has_one variables and putting in the associated model name in the array?

I've never used this particular ORM but I do use Doctrine. If the one you are using works in much the same way then the simple answer to your question is - yes! With Doctrine you set up all relationships in the model classes. The ORM will then manage it all for you. So, for example, if you instantiate a new task object...
$task = new Task();
Then you can access the relationship with the Project table by simply writing
$task->Project;
I must stress that the above code is not written for datamapper so might not work as is, but I hope it clears things up for you. It sounds like you do understand the documentation but just don't believe it!!!!

That is all you have to do as long as your database structure fits the layout expected by Datamapper Overzealous.
I've been using this ORM in a project I've been building and for the most part, it's been extremely helpful and time saving.

Related

Where to put custom SQL code in CakePHP 3?

I'm building an application in CakePHP 3. It uses a number of legacy databases which are not built in the Cake conventions.
I do not want to use any of the ORM features Cake provides, as it's more tedious to set up all the relations than just write "Raw SQL". We are also not going to make any changes to the database structures, so the ORM is a non-starter. So I'm going to write raw SQL queries for everything.
However, I'm not sure where this code would be put. I've read https://book.cakephp.org/3.0/en/orm/database-basics.html#running-select-statements but it doesn't say where you actually put that code.
I don't want to put my queries in a controller ideally since that defeats the purpose of MVC.
All I really need is one Model where I can put all my queries in different functions and reference them in my Controller(s).
In Cake 2.x it was easy to just create a model under app/Model/ then load it (loadModel) where needed in controller(s). But with the new Cake 3.x Table and Entity spaces, I'm not sure how this fits in?
I've also read up on Modelless Forms but don't think they're right either. For example the initial page of the application shows a list of chemicals which is just a SELECT statement - it doesn't involve forms or user input at all at this stage.
Obviously there will also be situations where I need to pass data from a Controller to the Model, e.g. queries based on user input.
As mentioned in the comments, I would suggest to not ditch the ORM, it has so many benefits, you'll most probably regret it in the long run.
Setting up the tables shouldn't be a big deal, you could bake everything, and do the refactoring with for example an IDE that does the dirty work of renaming references and filenames, and then set up the rules and associations manually, which might be a little tedious, but overally pretty simple, as there shouldn't really be much more to configure with respect to the database schema, than the foreign keys, and possibly the association property names (which might require updating possible entities #property annotations too) - maybe here and there also conditions and stuff, but oh well.
That being said, for the sake of completeness, you can always create any logic you want, anywhere you want. CakePHP is just PHP, so you could simply create a class somewhere in say the Model namespace (which is a natural fit for model related logic), and use it like any other class wherever needed.
// src/Model/SomeModelRelatedClass.php
namespace App\Model;
class SomeModelRelatedClass
{
public function queryTheDatabase()
{
// ...
}
}
$inst = new \App\Model\SomeModelRelatedClass();
$results = $inst->queryTheDatabase();
See also
Cookbook > Database Access & ORM > Associations - Linking Tables Together > BelongsTo Associations

Using a single flexible model

A quick question this time about the M in Mvc.(using codeigniter, but the question is general)
Suppose I have several models that are responsible for accessing several tables in my database, Is it frowned upon making one flexible model that can deal with everything?
specifically in php-codeigniter, for example:
$this->MY_model->getByID($table,$ID)
So this example code can be used to get by ID of any table I want thus saving me time and I'm able to reuse most of my model code.
This of course can be expanded further
$this->MY_model->update($table,$info) as an example.
So my question is, If all of the above is okay, Where is the 'limit' to such operations? Naturally we wouldn't want something really specific in this type of model, like this method:
$this->MY_model->getAllActiveUsers()
My basic approach is this:
Any method that can be used in more than one table should be used in the extended model.
Any method that should be used in only one table, should be in it's own model.
Just to be clear i'm not looking for an opinion, But rather wondering what's the standard approach to these issues.(for example, imagine an application with 50 models, should CRUD be written for all 50 of them?)
Thanks in advance!
What you are mulling about is pretty standard operation for most Codeigniter developers. If you are going to be doing a lot of CRUD in the DB, then it makes sense to add a set of generic CRUD methods to your base MY_model and then extend it. If you do a search on Google...you'll likely get results for 100s of people who have setup their own base models including CRUD and other common methods used by most Codeigniter projects...here are just a couple:
https://github.com/jamierumbelow/codeigniter-base-model
https://github.com/jenssegers/CodeIgniter-My-Model
should CRUD be written for all 50 of them?
No. You would extend your base model and use it's generic CRUD methods where they make sense and just override certain properties (table name). Then, if you needed something more specific you could create additional, more granular methods in your new model as you suggested.

Do extremely simple tables still require their own model class?

I've been using laravel (php mvc framework) for a few weeks now. Currently I am creating a model for every single non-pivot table. Even tables as simple as:
id (unsigned int (PK)) | usertype (varchar(20))
1 | guest
2 | member
3 | Moderator
Because it makes it easier to relate my other models to them using the eloquent ORM.
I was wondering if its normal to create models for such simple tables for the sake of utilizing an ORM or if there is a better approach?
Currently my application is functioning using models for these tables, but I still want to make sure I am picking up good coding conventions while I'm learning.
Thanks in advance.
Here comes the long answer: YES!
I don't know when or why model became a synonym to entity, but this leads to confusion.
According to MVC inventor, Trygve Reenskaug, in the original MVC article:
DEFINITION
A Model is an active representation of an abstraction in the form of data in a computing system
[...]
The models are represented in the computer as acollection of data together with the methods necessary to process these data.
So, many people nowadays define (incorrectly) models as data representation, or the data storage or something else, but this is wrong.
Model deals with your application logic and this INCLUDES data abstraction, data storage, data processing, etc.
I use to call my data abstractions an Entity instead of model. My application model layer is called Service or Application Model. My storage layer is called just Storage and so on... All of this togheter is what we can call Model
That being clarified, now we can go on...
You said:
Because it makes it easier to relate my other models to them using the eloquent ORM.
That's enough!
Nothing keeps you away from using plan txt files as storage, but if your data relate to others, then you should look for a database.
Eloquent is an ORM (Object-Relational Mapping) and so, it relies on a database behind it. If you use txt files, how would do to recover users by their user type?
I'm not used to frameworks, but most of them generate entities automatically, you just need to declare them...
If some entity has no business logic and you just need to store it, so you don't need a "full model" for it. And that's what you're doing.
Hope I convinced you...

Using models in laravel 4

Just really what the title says, does anybody have a decent explanation on how to use models properly in laravel 4? I'm fine with using the pre-existing User model. But I read somewhere that queries and such should be done in a model of your own.
So what I have is basically a form where you can make a status update (like facebook) and it stores it in a database but the query is run through the controller.
I want it to be done through a model.
Any information on this would be great! Thanks in advance
It's a broad question and right place to learn about how to use model in Laravel-4 is the laravel site itself, but anyways.
Actually, model is the the place where you should keep the business logic in any MVC framework, it could be database related or anything else that is the heart of the application and controller and View are just two parts of the application whose responsibility is only communicate to the model, fetch data and present it to the user but all the data processing should be done in the model and controller should be kept slim and view is only a mechanism to present the user a UI.
So, if you want to have a User model in your application (laravel-4) then you may extend it from Eloquent like
class User extends Eloquent{
// code goes here
}
and then call it's methods from the controller, like
$user = User::get(1);
then passing it to the view like
return View::make('viewname', $user);
That's it. But, if you think, where the find method come from then, it's because, you have extended the Eloquent model and in that model all the necessary methods (find e.t.c) are available and your User model inherited the behavior of Eloquent model, so you can use all the methods from User and it's not necessary to a single method in your User model unless you need to write some special methods for that User model, like relationship functions and so. well, the perfect place to seek help or to know the basic about it is the Laravel site, try to understand it from there and if you fail or just stuck anywhere then come here to ask with specific problem. Also, check Basic Database Usage and Query Builder.
BTW, you may check this post for a detailed answer on model of MVC.

Designing a Zend model for multiple tables together?

i am using Zend Framework to build a web interface for setting up ACL - permission rights - for users of a custom CMS. Since the ACL data is spread in 5 tables(users, groups, permissions, urls=action+controller, nice permission name for the user to understand) and i have only one controller with the four basic CRUD(create, list, update, delete) operations i was wondering what is the best way to do it?
All the examples in my books i've seen that each model extend Zend_Db_Table_Abstract and thus represents one table.
I was thinking i have to do a model that doesn't extend zend_db_table_abstract and then write the queries that i need by hand thus limiting myself to mysql database only?
p.s. please do not argue over the acl database structure
thank you
The definition of the Table Data Gateway pattern is
An object that acts as a Gateway to a database table. One instance handles all the rows in the table.
That's why you won't see it used any differently in Zend Framework. It's a Data Source Architectural Patterns while the thing you are asking about is a Domain specific class.
What you are encountering is Impedance Mismatch, meaning your Business Objects dont match the structure of your Database Design. The common solution is to use a DataMapper or an ORM to handle that for you.
The other solution would be to create a View in your database that joins the tables in a way that maps 1:1 to your required business objects. Then add a Zend_Db_Table for that view. You'd still have to come up with custom create, update, delete logic though. That's not data mapping though, but if you don't have any Business/Domain classes to map to, it's fine.

Categories