DB::table($table)->with($relation); it's possible? - php

If I use models this is easily resolved, but if I don't have the availability of using models, would it be possible to get the result equivalent to ->with() with DB::table?

No, Here is why
Laravel models are using Eloquent, which is an ORM library.
For example, a class model could have many teachers relations, and if you want to fetch a class with all the teachers, you could do something like:
$class = Classes::with('teachers')->find($id);
// $class->teachers contain all the teachers in the given class
With the query builder, you would need to do something like
$class = DB::table('classes')->find($id);
$teachers = DB::table('teachers')->where('class_id', $class->id)->get();
You can look into the documentation: https://laravel.com/docs/5.6/eloquent
Ref Thread

No this is not possible Now,
Because DB row not supported elequent relation
you should use by ORM formate.
Here is some example :-
$user = user::with('school')->get();

Related

use DB::table() or Model::all() Laravel's Eloquent

I would know why many people use $users = DB::table('users')->get(); instead $users = Users::all(); in Laravel projects ? What is reason ?
Regards
You can do this because Model and the DB facade both implement functions that yield a Builder instance.
https://laravel.com/api/5.2/Illuminate/Database/Eloquent/Model.html
https://laravel.com/api/5.2/Illuminate/Database/Query/Builder.html
The difference is, instances of Model have properties which set up a Builder with predesignated information, like table, and also provide it with events, relationship information, specific static bindings, and a bunch of other handy helpers that constrain to objects and make object-oriented programming easier.
So yes, you can use a model and then take the query Builder object and change its table (just like you can change anything else about a Builder), but it's fighting a system specifically designed to make query building easier.
At heart, what Laravel does is take the Symfony2 framework and streamline it so everything is simpler. Models are one such instance of this.
From the Laravel
public static function all()
{
$input = array_merge(static::get(), static::query(), static::file());
// ....
return $input;
}
So all() calls get() and returns it's contents along with query(), and file() the $_FILES superglobal.
Preference will obviously depend on circumstance. I personally choose to use Input::get($key, $default) as I usually know what I am after.

Why can't I access laravel relationship columns if I create new instance instead of using let's say "Article::all()"?

I'm confused to why can't I access the relationship I setup if I use this code:
$products = new Products();
If I use this, I can access my laravel relationship columns.
$products = Products::all();
What's the difference?
In your first example you are instantiating a regular php object, in the second example you are allowing laravel to instantiate the object. In such a case you are actually calling a named constructor that will utilize a static boot() method that is taking care of a lot of the heavy lifting under the hood.

extending zend db select

I am building a CMS kind of site, There will be lot of admin users. ACL was in place for business layer. But now we want to apply custom ACL logic to models based on city in which admin user belongs.
For eg:
Admin user is from New York. He can view the content related to New York City.
I have lot of queries built with Zend_Db_Select in the models. Now I have change the queries everywhere. Is there a way, I can add the logic ->where('u.city_id = ?', $admin_user_city_id)
for each and every query.
Thanks in advance.
Thanks
Venu
I think that you might not need to extend Zend_Db_Table_Select. You can do what you're looking for by only extending Zend_Db_Table_Abstract with a My_Db_Table_Abstract that all your models will extend too. In that abstract class, you'll extend the default select() that returns a Zend_Db_Table_Select and, before returning it, you just add your where clause to it.
Thus, everytime you'll call a select with $myModel -> select() it will already contain your where clause.
abstract class My_Db_Table_Abstract extends Zend_Db_Table_Abstract
{
public function select($withFromPart = self::SELECT_WITHOUT_FROM_PART)
{
$select = parent::select($withFromPart);
# Retreive $admin_user_city_id
$select -> where('u.city_id = ?', $admin_user_city_id);
return $select;
}
}
Of course that also implies that you have made the correct join to your u table somewhere depending on the model you're on.

How can I get Zend Db to return a rowset rather an array when performing a UNION query?

I have a result set that is the result of a MySQL UNION query. The code I am using to fetch the data is:
$union_select = $PagesTable->getAdapter()->select()
->union(array('(' . $legal_resources_select . ')', '(' . $pages_select . ')'));
$PagesTable->getAdapter()->fetchAll($union_select)
$PagesTable extends Zend_Db_Table_Abstract. The full select is too big to post here and I don't think it is relevant to this particular question. If I am wrong let me know.
Currently this is returning an array of results, but I want it to return a rowset object. I must also be able to specify the $_rowClass. This is necessary so I can add methods for formatting and manipulating the returned values.
Is this possible?
You cannot. The result set you are fetching is a composite, and not a set of Rows from the DB, so even if it were possible, its a pretty bad idea.
Zend_Db_Table is an implementation of the Table Data Gateway pattern more than Active Record.
What you describe would be possible usually under Active Record, and to do so, I'd suggest looking at Doctrine 1.2 rather than Zend_Db_Table.
BTW, if you want to specify the rowClass or rowsetClass, you can do that with the Zend_Db_Table class by calling the following methods
Using Zend_Db_Table's methods setRowsetClass and setRowClass:
class RowTable extends Zend_Db_Table_Abstract {
private static $_instance;
protected $_name = "tableName";
protected $_primary = "primary_key_id";
# over-write the default class Zend_Db_Table_Rowset_Abstract
# make sure the following classes are inside the include-path
private function __construct($rowClass, $rowsetClass) {
$this->setRowsetClass("ContributionList");
$this->setRowClass("Contribution");
}
}
$tableObject = new RowTable("RowClass", "RowsetClass");
By the way, I know this is really old, but the ones who get to this page should know that, a Zend_Db_Adapter always returns arrays, so when you use the Zend_Db_Table::getAdapter method, you are actually getting away from your table class and using the fetch method contained on the adapter class which returns array, rather than the Zend_Db_Table::_fetch which returns objects under the Data Gateway pattern.
So the first answer is wrong, the result set will be a row-set with many row objects but without what doctrine calls data hydration, so expect many redundant data on the row objects.
I see this mistake done by a lot of people where I work, I wonder why so many people uses the getAdapter method. Another thing to mention is that, when you use the getAdapter to get the select object, you are not getting the right select object, you are getting a Zend_Db_Select and you will need a Zend_Db_Table_Select so u can use on the Zend_Db_Table::_fetch method which is used by the fetchAll and fetchRow methods.
Cheers.

CodeIgniter, models, and ORM, how to deal with this?

I'm starting with CodeIgniter and after several hours diving in Google I'm a bit confused.
Let's try to explain my question with a easy example: I have a table 'car' with the fields 'name' and 'color'. Therefore I want to have a php class Car, so that my code could look finally like this:
$car = new Car('BMW', 'red'); //new $car Object
$car->save(); //this will make an SQL insert to the table 'car'
//Lets query all cars
$cars = Car::get_all();
//cars will be an array of Car objects, (not a set of rows!)
Therefore, I am looking for something pretty similar to what you have in RubyOnRails or Django (Python). I need to handle all kind of relationships, and to be able of write code in a true OOP+MVC way.
These are my failed approaches to get it:
Using an external ORM (DataMapper, Doctrine, AcidCrud...)
They either requires too many settings, or they handle relationships in a poor way.
Using CodeIgniter classes (to extend the CodeIgniter's Model class)
class Car extends Model{
public function Car($name='',$color='')
{
$this->name = $name;
$this->color = $color;
parent::Model();
}
public function save()
{
$data = array(
'name' => $this->name ,
'color' => $this->color
);
$this->db->insert('cars' $data);
}
And so on... Problem with this approach is that if a do a var_dump() of a $car object, I see that it contains a lot of stuff from the CodeIgniter, such as the objects CI_Config, CI_Input, CI_Benchmark, etc. Therefore I think this is not a good solution, because each object of my class Car, it will contain a lot of repeated data, (it will have a poor performance!), isn't it?
Not using the CodeIgniter's models
I could make my models without extending them from CodeIgniter's Model class, and then using the regular PHP5 constructor (__construct() instead of function Car()), but problem in this case is: how I access to the $db object to make querys using the CodeIgniter's ActiveRecord? and, how I load the models (its classes) within the controllers?
You probably want something like this:
class Cars {
//List all neccessary vars here
function __construct() {
//get instance of Codeigniter Object and load database library
$this->obj =& get_instance();
$this->obj->load->database();
}
//You can now list methods like so:
function selectCar($name, $color) {
$this->obj->db->select('color')->from('car')->where('color', $color);
$query = $this->obj->db->get();
switch ($query->num_rows()) {
case 0:
return false;
break;
default:
return $query->result();
break;
}
}
Hope that helps!
Try with Doctrine, is a great ORM and can be easily integrated in CodeIgniter.
take a look the the codeigniter wiki page for ORM
http://codeigniter.com/wiki/ORM/
For future Googlers, here is a tutorial I wrote up about how to integrate CodeIgniter 2 with Doctrine 2.
Let me know if you have any issues.
I had good luck with using Propel with codeigniter.
check out GAS ORM it sounds pretty good, handy and easy to use.
some features of this ORM implementation for CodeIgniter:
Supported databases : cubrid, mssql, mysql, oci8, odbc, postgre, sqlite, sqlsrv. (including PDO, if you keep sync with CI repo)
Support multiple database connections.
Support multiple relationships.
Support composite keys (for key that define relationships).
Auto-create models from database tables and vice versa.
Auto-synchronize models-tables by creating migrations file.
Per-request caching.
Self-referential and adjacency column/data (hierarchical data).
Eager Loading to maximize your relationship queries (for performance manner).
Various finder methods (can chained with most of CI AR) and aggregates.
Validation and auto-mapping input collection with minimal setup.
Hooks points to control over your model.
Extensions to share your common function/library across your model.
Transactions and other CI AR goodness.
Included phpunit test suite to ensure most of API consistency.
there is one form with spark support -> so it's easy to install
What you want to do is create a library that extends the ActiveRecord class. Some people are ahead of you:
http://codeigniter.com/wiki/ActiveRecord_Class/
good mods in the thread, here:
http://codeigniter.com/forums/viewthread/101987/
If you're looking for ORM methods that are general to your app, just extend the ActiveRecord class. For my application, knowing the structure of a table allows me to scaffold (auto-generate) forms, and do other mapping. I do API-to-API mapping, so I include a GetStructure() method in MyActiveRecord and build other things from there.
(RoR snickering can bugger off now)
Edit: while I am a fan of the scope and power of Doctrine, I think it's demand for command-line usage places it beyond the spirit of CI. What's right for you is what's right for you, but if I'm going to use Doctrine, I might as well use Symfony, right? Or RoR, for that matter, right?? See where I'm gong with this? Right tool for the right time.
I used CodeIgniter with Propel and they really mixed well. I've used like that for a while and got a few webapps working that way. Since I found a few awful ways to do it ( some included modifiying Apache's configuration!!). I decided to publish a blog post on how to do it. You can read it here.
Hope I can help!
I think php-activerecord is a very good drop-in ORM. I've used it with the Slim Framework a few times and I think it would be a great alternative to using CI's native model class. Here is some sample code and the link:
$post = new Post();
$post->title = 'My first blog post!!';
$post->author_id = 5;
$post->save();
PHP ActiveRecord
i know this is quite old, but for those who are just using codeigniter now and wannt to use an orm with it can use this tutorial to integrate propel with codeigniter
http://llanalewis.blogspot.com/2013/06/installing-propel-in-codeigniter.html

Categories