Virtual private databases with Eloquent - php

I want to have variable number databases that appear to be separate but are actually in one MySQL database.
These separate instances should be creatable and destroyable inside the application and while normal users work inside a single database instance, the system administrator could see all of them.
This concept seems similar to Oracle's Virtual Private Databases.
I am willing to implement the functionality in Laravel app but I am not sure how to do it.
I would add column instance_id to tables that I want to be instanced and the plain way would be to include something like where('instance_id', Auth::user()->instance_id) in every query, but this is nightmare to add that to every query...
How can I hide that in a neat way so I could either use something or extend improved model class whenever I need a model to be instanced. I want to do it in a way that I could also query the whole table ignoring instancing if I specify that.

Related

Modifying the SQL Eloquent uses per connection

I'm using the latest version of Laravel to connect to multiple data sources. One of those sources is an old Oracle database that contains a lot of white space thanks to some ancient software requiring string length. Despite this constraint, the fields have since been edited by new software with different requirements, and the columns are all varying length (and thus unknown).
On account of this, I need to edit the SQL that accesses it in order to wrap some pieces of the queries in trim()s. For instance,
$customer = Customer::whereRaw("RTRIM(\"ID\") = TO_CHAR($id)")->get();
I'd like to be able to merely call the find method:
$customer = Customer::find($id)
This is just one example. Pretty much all of the default functions are broken because the queries need some kind of trim prepended to them. I understand how I can affect the dynamic portion of the query, but I need to edit the column ahead of that. Sorry if this is a dumb question and I've just missed something in the documentation.
The easiest way to do this is to create a class that extends Eloquent, with the function for the query. Then modify all of your models to extend the new class instead of Eloquent. This way the models will have all the functionality of Eloquent as well as the functions you create.

Models in Laravel 5

I'm doing a web app here using Laravel + AngularJS and I have a question.Do I need a model for each table that I have in my database? There are 87 tables in my database and I need to query all of them according to with the input that the User wants.
I just want to make sure with all tables must have a model file or if just one is enough.
There are 2 ways by which you can access your DB tables:
Eloquent ORM (dependent on Models)
DB Facade Query Builder(independent on Models)
Former, is more clean and best approach to perform DB query and related task, whereas latter is not clean, and it is going to be difficult for you to manage large application, as you told there are 80+ tables in your application.
Also, if you're using Eloquent way, then it's also a better to have a base model, which will have common code which you can inherit in child models. Like if you want to store "user id" who did some DB changes, then in the boot function, you can write Auth::id() and assign that value to changed_by field on your table.
In DB Facade way, you've to hard code table name every time you're performing DB operation, and which leads to inconsistency when you found that you've to change the name of the table, it's a rare scenario still it'll be difficult to manage if in a file there are multiple tables DB operation going on. There are options like, creating a global table name variable which can be accessed to perform DB operation.
Conclusion:
Yes, creating 80+ model for implementing Eloquent way is painful, but for a short term, as the application grows it will be easy for you to manage, it will be good for other developer if they start working on it, as it will give a overview of DB and it will improves code readability.
It depends on how you'd like to handle queries.
If you'd like to use Eloquent ORM, you need model classes to handle objects and relationships. That is a model for a table, except intermediate relationship tables, which may be accessed through pivot attribute.
Raw SQL queries are also supported. You don't really need model classes for them, as each result within the result array will be a PHP StdClass object. You need to write raw SQL though.
See Laravel documentation.

Why separate Model and Controller in MVC?

I'm trying to understand the MVC pattern in Phalcon.
In my current application I only need ONE template file for each table. The template contains the datagrid, the SQL statement for the SELECT, the form, add/edit/delete-buttons, a search box and all things necessary to interact with the database, like connection information (of course using includes as much as possible to prevent duplicate code). (I wrote my own complex framework, which converts xml-templates into a complete HTML-page, including all generated Javascript-code and CSS, without any PHP needed for the business logic. Instead of having specific PHP classes for each table in the database, I only use standard operation-scripts and database-classes that can do everything). I'm trying to comply more with web standards though, so I'm investigating alternatives.
I tried the INVO example of Phalcon and noticed that the Companies-page needs a Companies model, a CompaniesController, a CompaniesForm and 4 different views. To me, compared to my single file template now, having so many different files is too confusing.
I agree that separating the presentation from the business logic makes sense, but I can't really understand why the model and controller need to be in separate classes. This only seems to make things more complicated. And it seems many people already are having trouble deciding what should be in the model and what should be in the controller anyway. For example validation sometimes is put in the model if it requires business logic, but otherwise in the controller, which seems quite complex.
I work in a small team only, so 'separation of concerns' (apart from the presentation and business logic) is not really the most important thing for us.
If I decide not to use separate model and controller classes,
what problems could I expect?
Phalcon's Phalcon\Mvc\Model class, which your models are supposed to extend, is designed to provide an object-oriented way of interacting with the database. For example, if your table is Shopping_Cart then you'd name your class ShoppingCart. If your table has a column "id" then you'd define a property in your class public $id;.
Phalcon also gives you methods like initialize() and beforeValidationOnCreate(). I will admit these methods can be very confusing regarding how they work and when they're ran and why you'd ever want to call it in the first place.
The initialize() is quite self-explanatory and is called whenever your class is initiated. Here you can do things like setSource if your table is named differently than your class or call methods like belongsTo and hasMany to define its relationship with other tables.
Relationship are useful since it makes it easy to do something like search for a product in a user's cart, then using the id, you'd get a reference to the Accounts table and finally grab the username of the seller of the item in the buyer's cart.
I mean, sure, you could do separate queries for this kind of stuff, but if you define the table relationships in the very beginning, why not?
In terms of what's the point of defining a dedicated model for each table in the database, you can define your own custom methods for managing the model. For example you might want to define a public function updateItemsInCart($productId,$quantity) method in your ShoppingCart class. Then the idea is whenever you need to interact with the ShoppingCart, you simply call this method and let the Model worry about the business logic. This is instead of writing some complex update query which would also work.
Yes, you can put this kind of stuff in your controller. But there's also a DRY (Don't Repeat Yourself) principle. The purpose of MVC is separation of concerns. So why follow MVC in the first place if you don't want a dedicated Models section? Well, perhaps you don't need one. Not every application requires a model. For example this code doesn't use any: https://github.com/phalcon/blog
Personally, after using Phalcon's Model structure for a while, I've started disliking their 1-tier approach to Models. I prefer multi-tier models more in the direction of entities, services, and repositories. You can find such code over here:
https://github.com/phalcon/mvc/tree/master/multiple-service-layer-model/apps/models
But such can become overkill very quickly and hard to manage due to using too much abstraction. A solution somewhere between the two is usually feasible.
But honestly, there's nothing wrong with using Phalcon's built-in database adapter for your queries. If you come across a query very difficult to write, nobody said that every one of your models needs to extend Phalcon\Mvc\Model. It's still perfectly sound logic to write something like:
$pdo = \Phalcon\DI::getDefault()->getDb()->prepare($sql);
foreach($params as $key => &$val)
{
$pdo->bindParam($key,$val);
}
$pdo->setFetchMode(PDO::FETCH_OBJ);
$pdo->execute();
$results=$pdo->fetchAll();
The models are very flexible, there's no "best" way to arrange them. The "whatever works" approach is fine. As well as the "I want my models to have a method for each operation I could possibly ever want".
I will admit that the invo and vokuro half-functional examples (built for demo purposes only) aren't so great for picking up good model designing habits. I'd advise finding a piece of software which is actually used in a serious manner, like the code for the forums: https://github.com/phalcon/forum/tree/master/app/models
Phalcon is still rather new of a framework to find good role models out there.
As you mention, regarding having all the models in one file, this is perfectly fine. Do note, as mentioned before, using setSource within initialize, you can name your classes differently than the table they're working on. You can also take advantage of namespaces and have the classes match the table names. You can take this a step further and create a single class for creating all your tables dynamically using setSource. That's assuming you want to use Phalcon's database adapter. There's nothing wrong with writing your own code on top of PDO or using another framework's database adapter out there.
As you say, separation of concerns isn't so important to you on a small team, so you can get away without a models directory. If it's any help, you could use something like what I wrote for your database adapter: http://pastie.org/10631358
then you'd toss that in your app/library directory. Load the component in your config like so:
$di->set('easySQL', function(){
return new EasySQL();
});
Then in your Basemodel you'd put:
public function easyQuery($sql,$params=array())
{
return $this->di->getEasySQL()->prepare($sql,$params)->execute()->fetchAll();
}
Finally, from a model, you can do something as simple as:
$this->easyQuery($sqlString,array(':id'=>$id));
Or define the function globally so your controllers can also use it, etc.
There's other ways to do it. Hopefully my "EasySQL" component brings you closer to your goal. Depending on your needs, maybe my "EasySQL" component is just the long way of writing:
$query = new \Phalcon\Mvc\Model\Query($sql, $di);
$matches=$query->execute($params);
If not, perhaps you're looking for something more in the direction of
$matches=MyModel::query()->where(...)->orderBy(...)->limit(...)->execute();
Which is perfectly fine.
Model, View and Controller were designed to separate each process.
Not just Phalcon uses this kind of approach, almost PHP Frameworks today uses that approach.
The Model should be the place where you're saving or updating things, it should not rely on other components but the database table itself (ONLY!), and you're just passing some boolean(if CRUD is done) or a database record query.
You could do that using your Controller, however if you'll be creating multiple controllers and you're doing the same process, it is much better to use 1 function from your model to call and to pass-in your data.
Also, Controllers supposed to be the script in the middle, it should be the one to dispatch every request, when saving records, when you need to use Model, if you need things to queue, you need to call some events, and lastly to respond using json response or showing your template adapter (volt).
We've shorten the word M-V-C, but in reality, we're processing these:
HTTP Request -> Services Loaded (including error handlers) -> The Router -> (Route Parser) -> (Dispatch to specified Controller) -> The Controller -> (Respond using JSON or Template Adapter | Call a Model | Call ACL | Call Event | Queue | API Request | etc....) -> end.

PHP install method in a class what requires database tables/columns

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.

PHP database abstraction: Define the model once, generate the code but deal with plain data instead of active record objects

I am searching for a database abstraction layer in future PHP projects. Until now I have worked with plain SQL-commands and arrays on the one hand fully featured ORMs like Doctrine on the other hand.
I don't like ORM because most of the time the job is to get a list of data from the database and to send it to the template engine. Both work fully fine with arrays and there's no need to make it all complicated by capsule the data in an object when the template just needs the plain array. I don't like the plain-SQL approach either because for the simple CRUD stuff I have to write everything myself and also I don't like to maintain two models of my data (one in the DB and the other within my database access object).
Is there something which let's me define the model one time only and generates the elementary stuff for me (like in Doctrine) but which saves me from the active record pattern?
The db is not a model, its the raw data source, and the model is, in thoery, more than just the data fields, it should also be the methods that affect the model's data.
You are always going to have to tell the program what to insert and where into the db, even if you use a library that encapsulates the sql or if you write it yourself.
If you find yourself writing the similar "insert" and "select" commands over and over, then its time to design some functions or classes.

Categories