Laravel with([]) select only some columns of the relation - php

Edit
This question is unique because it poses unique problems such as:
relations within the with components. (items.product.stockManagement).
A large amount of components, this causes the accepted answers of the linked question to not apply.
Suppose you have a large with() like the following:
$order = Order::with([
'company',
'complaints',
'person',
'items',
'items.product',
'items.product.stockManagement',
'status',
])->findOrFail($id);
How can I then select with all their relations but specific columns for some of them?
$order = Order::with([
'company', // select only id,name, size
'complaints', // select only id, name , body
'person',
'items',
'items.product', // select only id, name , price
'items.product.stockManagement',
'status', // select only id
'items.product.media',
'items.product.mainProduct',
'items.product.mainProduct.media'
])->findOrFail($id);

Like this:
$order = Order::with([
'company:id,name,size',
'complaints:id,name,body',
'person',
'items',
'items.product:id,name,price',
'items.product.stockManagement',
'status:id',
'items.product.media',
'items.product.mainProduct',
'items.product.mainProduct.media'
])->findOrFail($id);
The documentation is very brief about the loading of specific columns (you even have to scroll down a bit to the heading that says "Eager Loading Specific Columns").
You may not always need every column from the relationships you are retrieving. For this reason, Eloquent allows you to specify which columns of the relationship you would like to retrieve:
$books = App\Book::with('author:id,name')->get();
Note:
When using this feature, you should always include the id column and any relevant foreign key columns in the list of columns you wish to retrieve.

You can also provide a callback for some more advanced relation querying.
Order::with([
'company' => function ($q) {
$q->select('id', 'name');
}
])

I faced the same problem. You need to specify the foreign id not id (primary key).
For example:
Data::with('other:id,name')->get();
It won't be working if you customize the foreign name.
So, you need to add your foreign column name completely.
Data::with('other:foreign_id,name')->get();
And that will work!

$order = Order::with(
['company' => function($query) {
$query->select('id','name','size')
}),
'complaints' => function($query) {
$query->select('id','name','body')
}),
'person',
'items',
'items.product' => function($query) {
$query->select('id','name','price')
}), 'items.product.stockManagement','status'=> function($query) {
$query->select('id')
}),'items.product.media', 'items.product.mainProduct', 'items.product.mainProduct.media'])->findOrFail($id);

Related

Foreign key issue while inserting data in child table Laravel

I am trying to insert data in orders table and then save order details in order_details table. Following is the code that I'm trying
$order = Order::create($request->all());
$order->order_detail()->insert($request->order_detail); //$request->order_detail is an array
In my model I have provided relationships
Order Model
public function order_detail(){
return $this->hasMany(OrderDetail::class, 'order_id');
}
Order Detail Model
public function order(){
return $this->belongsTo(Order::class,'order_id');
}
but it returns me General error: 1364 Field 'order_id' doesn't have a default value as order_id is a foreign key in order_details table
How can I do it without giving order_id manually
I am going to assume that $request->order_detail is an array of many order_details.
The problem with insert is that you are not using Eloquent but the query builder, therefore Laravel is not able to fill the order_id by itself, if you use createMany instead it will be able to do so:
$order = Order::create($request->all());
$order->order_detail()->createMany($request->order_detail);
From the docs:
You may use the createMany method to create multiple related models:
$post = App\Post::find(1);
$post->comments()->createMany([
[
'message' => 'A new comment.',
],
[
'message' => 'Another new comment.',
],
]);
Since your $request->order_detail isn't gonna contain order_id. You can take that from the newly created $order.
$order = Order::create($request->all()); // upon create, you can access the order_id by doing $order->id
$orderDetails = [];
foreach($request->order_detail as $details) {
$orderDetails[] = [
array_merge($details, ['order_id' => $order->id]);
];
}
$order->order_detail()->insert($orderDetails);
Sounds like a database issue. The column order_id has AUTO_INCREMENT, meaning it would generate a number upon insert.
Try inserting with phpMyAdmin to see whether AUTO_INCREMENT works. Or use SHOW TABLE STATUS and check AUTO_INCREMENT.

CakePhp3 select() in query more than one tier

Is it possible to get columns of tables which are two or more tables remote by using select()?
$rooms = TableRegistry::get('Rooms')
->find()
->contain(['Levels.Buildings'])
->toArray();
... this works, but returns ervery column of the three tables
$rooms = TableRegistry::get('Rooms')
->find()
->select(['Buildings.name'])
->contain(['Levels.Buildings'])
->toArray();
... this returns nothing, althought the generated select statement seems to be correct
You can only select fields in the primary query if you are handling a one-to-one relationship (i.e. hasOne or belongsTo). This is presumably your issue. In which case you need to specify the fields to include from your has-many relationship in the contain itself:-
$rooms = TableRegistry::get('Rooms')
->find()
->contain([
'Levels' => [
'Buildings' => [
'fields' => 'name'
]
]
])
->toArray();
This is because CakePHP will perform a second separate query to retrieve the has-many associated model data for which you need to specify the query conditions within the contain.

Unable to get data from two tables in laravel

I am doing project in laravel.
Database Table 1
user_verification
------------------------------------------
'id', 'user_id', 'verified', 'verified_by'
Database Table 2
user
-----------------------------
'id', 'name', 'email', 'pass'
I want to get data as all users which are verified('verified' = 1) and name of user('verified_by' is user id from user table) who does verification.
My controller method is like,
public function verifiedProviders(){
//$user_data = sql query goes here...
return view('display',compact('user_data '));
}
for example:,
I want to display in blade file as follow
name:abc,
email:abc#gmail.com,
verified by: name (id present in *verified_by* field) from *user* table.
I am not getting how to get and display this data in laravel's blade file. How to use relationships eloquent method or database query. Thanks in advance.
User::select('name', 'email', 'u2.name as verified_by_name')
->join('user_verification', 'user_verification.user_id', '=', 'user.id')
->join('user u2', 'user_verification.verified_by', '=', 'u2.id')
->all(); // I guess
Of course you may want to limit your query to return only the first 25 results and display them, etc.
References:
https://laravel.com/docs/5.2/queries#joins
https://laravel.com/docs/5.2/queries#selects

Condition for related table ORM Kohana

For example I have 3 tables:
songs(id, song_name)
song_category(id, song_id, category_id)
categories(id, name)
I want to get songs which have categories with id higher than 5. I want to do it using ORM, not with simple SQL query. Is it possible to do it with one query like this:
$songs = ORM::factory("songs")->where("category.id > 5")
No, you cannot do this with a single Kohana ORM call.
The best way I have found to do it is something like this, which makes a modification to the SQL query that the ORM will generate:
// Get the basic "song" model
$songs = ORM::factory("songs");
// Get the information about how it is connected to
// the "category" model using the `through` model
$song_relations = $results->has_many();
$category_relation = $song_relations['categories'];
$through = $category_relation['through'];
// Join on `through` model's target foreign key (far_key) and `target` model's primary key
$join_col1 = $through.'.'.$category_relation['foreign_key'];
$join_col2 = $songs->object_name().'.'.$songs->primary_key();
$songs->join($through)->on($join_col1, '=', $join_col2);
// Now, filter on the
$songs->where($through.'.'.$category_relation['far_key'], '>', 5);
$arr = $results->find_all()->as_array();
You could save some code by hardcoding the values in the join method call, but this way leverages the ORM relation definitions that you already have.
This assumes that your Song model has the following code in it:
protected $_has_many = [
'categories' => [
'model' => 'category',
'through' => 'song_category',
'foreign_key' => 'song_id',
'far_key' => 'category_id',
]
];

Kohana 3 ORM: How to get data from pivot table? and all other tables for that matter

I am trying to use ORM to access data stored, in three mysql tables 'users', 'items', and a pivot table for the many-many relationship: 'user_item'
I followed the guidance from Kohana 3.0.x ORM: Read additional columns in pivot tables
and tried
$user = ORM::factory('user',1);
$user->items->find_all();
$user_item = ORM::factory('user_item', array('user_id' => $user, 'item_id' => $user->items));
if ($user_item->loaded()) {
foreach ($user_item as $pivot) {
print_r($pivot);
}
}
But I get the SQL error:
"Unknown column 'user_item.id' in
'order clause' [ SELECT user_item.*
FROM user_item WHERE user_id = '1'
AND item_id = '' ORDER BY
user_item.id ASC LIMIT 1 ]"
Which is clearly erroneous because Kohana is trying to order the elements by a column which doesn't exist: user_item.id. This id doesnt exist because the primary keys of this pivot table are the foreign keys of the two other tables, 'users' and 'items'.
Trying to use:
$user_item = ORM::factory('user_item', array('user_id' => $user, 'item_id' => $user->items))
->order_by('item_id', 'ASC');
Makes no difference, as it seems the order_by() or any sql queries are ignored if the second argument of the factory is given.
Another obvious error with that query is that the item_id = '', when it should contain all the elements.
So my question is how can I get access to the data stored in the pivot table, and actually how can I get access to the all items held by a particular user as I even had problems with that?
Thanks
By default, all of Kohana's ORM models expect the table's primary key to be 'id.' You need to set $_primary_key in your model to something else.
$user_item = ORM::factory('user_item', array('user_id' => $user, 'item_id' => $user->items));
I think you need to provide a single item_id value for this to work, not an array of objects.
Also, to find all entries for a single user you should be able to do this:
$user_items = ORM::factory('user_item', array('user_id' => $user));
Does that answer your question?

Categories