I have Products that have Models. I need to get some fields from all the Products and its Model slug. This is my code:
$query = Product::with('model');
$query->orderBy('order', 'asc')->orderBy('name', 'asc')->skip($skip)->take($take);
return $query->get(['id', 'name', 'front_image', 'back_image', 'slug']),
Its returning something like:
{
"id": 39,
"name": "ASD1",
"front_image": "adasdsa.jpg",
"back_image": "2evewa.jpg",
"slug": "asd1",
"model": null
}
How can I take model.slug?
The get method is used to tell eloquent to execute a query to the database.
To select only specific fields you can use the select method before get.
For example:
Product::with('model')->select('name', 'model.slug as model_slug')->get();
Related
I am using Laravel (PHP) and MySQL for my backend. I am creating methods for setting and getting information from the database. Those information are being send as a json to the frontend.
I can send table information like:
[
{
"id": 4,
"name": "Max"
},
{
"id": 5,
"name": "Eric"
}
]
For this I am using laravel methods like: DB::table('user')->select('user.id', 'user.name')->get();
However my friend who is doing the frontend want the following json code:
[
{
"id": 4,
"name": "Max"
"specific_user_price":{
"S":5.00,
"M":6.00,
"XL":8.00
}
},
{
"id": 5,
"name": "Eric"
"specific_user_price":{
"S":5.50,
"M":10.00,
"XL":15.00
}
}
]
"specific_user_price is a table and "S", "M", "XL" are columns which have different values depending on the user. I do not know how I can create specific_user_price as an array in a query. I can use group_concat but he needs the json like displayed above.
My idea was to create additional columns in user "size S price", "size M price" and "size XL price". However my friend want those values as an own array group, because some users only habe access to one size, so he would get null values.
Any ideas which method in PHP or Laravel I can use for that? Or is there a MySQL method for creating such thing in a query?
Firstly use Models, way easier to work with out of the box. Define your User model like this, with a relationship for the price.
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function specificUserPrice() {
return $this->hasOne(UserPrice::class);
}
}
You also need to have the UserPrice model defined.
use Illuminate\Database\Eloquent\Model;
class SpecificUserPrice extends Model
{
}
Laravel automatically transforms models, you can get away with the following code in the controller.
public function index()
{
return User::with('specificUserPrice')->get();
}
DB::table('user')->select(['id', 4],['name','max'])->get();
DB::table('user')[0]->get()
This gets you the first element in the array
Question: I have two tables how to fetch a customer's data using order's table user_id
"order": [
{
"id": 1,
"user_id": 4
},
{
"id": 2,
"user_id": 5
}
],
"customers": [
{
"id": 5,
"name": "Mohamed Raazi",
"phone": "777",
}
],
Following code will return only the last object of an array, i need to display all the objects from user table using a where condition in customers table
for ($x=0; $x<count($orders); $x++){
$customer = User::where('id',$orders[$x]->user_id)->get();
}
I would use the ::whereIn-method where you can provide an array of IDs to and get all the users with the provided IDs.
First you would have to reformat the $orders array that you have so that it contains only user IDs. I am guessing that you are using Eloquent to fetch the orders, then you can use the pluck-function in your Eloquent-statement:
$userIds = Order::where('statement', true)->pluck('user_id')->toArray();
Please note that the where-statement is not real, I just want to illustrate how you can call the pluck-method.
Another alternative is that you use the map function on the $orders-collection and return only user IDs:
$userIds = $orders->map(function ($order) {
return $order->user_id;
});
Once you have your user IDs in an array/collection you can use it in the whereIn-statement:
$users = Users::whereIn('id', $userIds)->get();
Then this would give you all the users that that are connected to the orders you have in your order-collection.
I have something like that:
$order = Order::with('user')->where('id', $id)->first();
It returns:
{
"id": 1,
"price": null,
"user": {
"id": 1,
"name": "jon"
}
}
Now inside my laravel code I want to get id of user. How is that possible?
because $order->user returns just null
Since above value returned by Order::with('user')->where('id', $id)->first(); is a collection so try chaining the result with pluck like below
Order::with('user')->where('id', $id)->first()->pluck(user.id);
Let me know if this works for you as I could not replicate it on my machine.
I am just confused on how this thing is working .
I have a M-M relationship between by Users and Roles. If I retrieve my user like the following :-
$user = Auth::User();//->with('roles')->get();
$roleName = $user->roles[0]->name;
return $this->sendResponse('User retrieved successfully',$user);
I get the following response :
{
"success": true,
"message": "User retrieved successfully",
"data": {
"id": 2,
"name": "dummy",
"email": "dummy#dummy.com",
"created_at": "2017-05-06 09:49:50",
"updated_at": "2017-05-06 09:49:50",
"tenant_id": 2,
"roles": [
{
"id": 1,
"created_at": "2017-05-06 06:26:55",
"updated_at": "2017-05-06 06:26:55",
"name": "Admin",
"permissions": null,
"pivot": {
"user_id": 2,
"role_id": 1
}
}
]
}
}
But, if I retrieve my user as :-
$user = Auth::User();//->with('roles')->get();
return $this->sendResponse('User retrieved successfully',$user);
I get the following resut :-
{
"success": true,
"message": "User retrieved successfully",
"data": {
"id": 2,
"name": "Ali",
"email": "ali#and-or.com",
"created_at": "2017-05-06 09:49:50",
"updated_at": "2017-05-06 09:49:50",
"tenant_id": 2
}
}
Why is this happening ? I expected the "first" posted result to the latter query.
Secondly, I did not modify the $user after the query in the first "method" how did it get its Roles attachment ?
I am sure there is an explanation, but I couldn't put my finger on it.
When retrieving a model, the User in this instance, relationships are not automatically also retrieved (Since on the database side this would require a second query while you might not even need the roles in a certain situation).
In your first example, by accessing the roles through $roleName = $user->roles[0]->name;, Laravel does the roles() query automatically, and also adds the roles object to the User (So it can be accessed again at a later point without needing to redo the query). This explains why the roles are 'magically' attached to your User model in the first example.
In your second example this query is not done automatically, so you do not get the roles relation in your response.
If you want to have access to the Users roles, then you could use the with() method like in your comment to eager load the relationship, but keep in mind that this implies doing the second query in order to get this data from the database.
Another option, if you always want the User model to have its Roles attached, would be to add roles to the $appends array of the model:
protected $appends = ['roles'];
This tells Laravel that the roles attribute is one which you always want available on your model, and it then does what is necessary to make this happen (In this case, query the relationship).
I am building API. I ran into issue when building responses such as this one:
{
"id": 1,
"name": "Some name",
"my_joined_table": {
"joined_table_id": "10",
"some_joined_table_field": "some value"
}
},
Joining tables as described in https://laravel.com/docs/5.2/queries would yield result such as:
{
"id": 1,
"name": "Some name",
"joined_table_id": "10",
"some_joined_table_field": "some value"
},
Instead of using join I could just run two queries, one for main table, second one for secondary and then just append second array to first one and spit JSON response, but it's a lot of queries and appending if list is big!
Example code which yields second result in pseudo-code:
$data = Model::select('id', 'name', 'my_joined_table.id as joined_table_id', 'my_joined_table.some_value some_value')
->leftJoin('my_joined_table', function($join) { //conditions_callback
})->get();
return response()->json($data);
Please advice.
EDIT2:
It seems that I can use with as follows:
$data = Model::with('my_second_table')->first();
return response()->json($data);
It does what I want, only the problem, that I cannot specify fields for both first and second tables using ->first($fields) and->with(['my_second_table' => function ($query) { $query->select('id', 'some_value'); }]) unless I specify primary key of second table in ->first($fields). How do I work around this?
TL;DR; Issue: http://laravel.io/bin/YyVjd
You can probably use Laravel Eloquent relationship to achieve it.
https://laravel.com/docs/5.2/eloquent-relationships#one-to-many
Or you can remap the returned data to a new response object using $appends.
Try something here,
http://laraveldaily.com/why-use-appends-with-accessors-in-eloquent/
This is just some clues and there is a lots work to do.
FYI, you can set $visible in your model to specify which attributes is visible.