Laravel, cant' get property of colletion - php

I have Collection form my Form obj, and iam trying to get all pages belongs to that form,
when I do $survey = Forms::find(68)->with('pages')->get(); Iam getting this:
Illuminate\Database\Eloquent\Collection {#522 ▼
#items: array:18 [▼
0 => App\Models\Forms {#562 ▼
#table: "forms"
#fillable: array:4 [▶]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:9 [▶]
#original: array:9 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▼
"pages" => Illuminate\Database\Eloquent\Collection {#596 ▼
#items: array:5 [▼
0 => App\Models\Pages {#628 ▶}
1 => App\Models\Pages {#632 ▶}
2 => App\Models\Pages {#633 ▶}
3 => App\Models\Pages {#634 ▶}
4 => App\Models\Pages {#635 ▶}
]
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
]
}
but can't get property of relations, when I do $form->pages Iam getting null
Its works fine for other property like questions (same relations)
here is my model:
class Forms extends Model
{
protected $table = "forms";
protected $fillable = array('name', 'description', 'status', 'token');
public function pages()
{
return $this->hasMany('App\Models\Pages');
}
public function questions()
{
return $this->hasMany('App\Models\Question');
}
}
class Pages extends Model
{
protected $table = "pages";
public $timestamps = false;
protected $fillable = array('name', 'description' ,'priority', 'token');
public function form()
{
return $this->belongsTo('App\Models\Forms');
}
}
and finally, method where Iam trying to get results:
public function index()
{
$survey = Forms::with('pages')->find(68);//Did update regarding to sugestion
dd($survey);
return view("pages.surveys", compact('survey'));
}
Thanks for any help.
Greg

I think you should reverse the order of the with() and find() functions.
$survey = Forms::with('pages')->find(68);
Note that find() actually executes the query, therefore you don't have to use get() again. As a rule of thumb: if you need to get only one result out of your query you should use first() or find() (the latter could also be used to retrieve collections), otherwise use all() or get() to fetch a collection of results.

$form = Forms::find(68);
dd($form->pages);
OR
$form = Form::find(68)->pages->get(); //It will return all the pages having relation
try this, It will first find form having id '68' then as per relation given it will fetch the records

Seems almost of your codes are okay. This might be a problem only with your foreign key. In your pages relationship in your forms, laravel will expect a foreign key in your pages table namely 'form_id' or 'forms_id' since you are not passing a second argument in your pages relationship. Make sure that in your pages migration your foreign key is set to to form_id also

when i do dd($survey);
App\Models\Forms {#513 ▼
#table: "forms"
#fillable: array:4 [▶]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:9 [▶]
#original: array:9 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▼
"pages" => Illuminate\Database\Eloquent\Collection {#521 ▼
#items: array:6 [▼
0 => App\Models\Pages {#552 ▼
#table: "pages"
+timestamps: false
#fillable: array:4 [▶]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:6 [▶]
#original: array:6 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
1 => App\Models\Pages {#553 ▶}
2 => App\Models\Pages {#554 ▶}
3 => App\Models\Pages {#555 ▶}
4 => App\Models\Pages {#556 ▶}
5 => App\Models\Pages {#557 ▶}
]
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}

Related

php laravel call function from collation \App\CourseStart->find(any)->students->count() with concatenate

in first i can write this \App\CourseStart->find(any)->students->count() and will work fine
put I am forced to concatenate the variables same $object->$k->count()
$object = (`\App\CourseStart->find(any)) collation laravel
App\CourseStart {#1309 ▼
#dates: array:2 [▶]
#fillable: array:15 [▶]
#connection: "mysql"
#table: "course_starts"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:6 [▶]
#original: array:6 [▶]
#changes: []
#casts: []
#classCastCache: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▶]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
#forceDeleting: false
}
$k = 'students' is relation
so $object->{$k} = \App\CourseStart->find(any)->students this work 100%
Illuminate\Database\Eloquent\Collection {#1310 ▼
#items: array:2 [▼
0 => App\Student {#1311 ▶}
1 => App\Student {#1314 ▶}
]
}
$object->{$k}->count(); work get resulte "2"
$f = ['count()','','']
now i try write this $object->{$k}->$f[0] and $object->$k->{$f[0]}
i have this msg error
Exception
Property [count] does not exist on this collection instance.
now how concatenate function count() to $object->{$k}
Not sure which address is appropriate for the question?
after some experiments
$f = ['count','','']// remove brackets of the functions
$f2 = $f[0];// assign to a variable for extracting the function from the array
$object->{$k}->$f2()// this will work
source: https://www.php.net/manual/en/functions.variable-functions.php
I tested it in a project of mine as beloved:
$x = Page::where ( 'slug', $page_slug );
$fA = ['count','get',''];
$f = $fA[0];
dd( $x->$f());

How to get the data of third table and second table from first table?

I have three tables : "Users", "tickets" and "events". I want to get tickets of the users and the details of tickets is in events. I want to get data from all table using relationships.
i need user and ticket of user and event of that ticket
Also am i doing it properly?
I have made relations with all the tables.
table structure is:
users
-username, user_id
ticket_orders
-user_id , ticket_id, event_id
events
-event_id, event_name
For Users
public function ticketOrder(){
return $this->hasMany('App\TicketOrder', 'user_id', 'user_id');
}
For tickets
public function user(){
return $this->belongsTo('App\User', 'user_id', 'user_id');
}
public function events(){
return $this->belongsTo('App\Event', 'event_id', 'event_id');
}
for events
public function ticketOrder(){
return $this->hasMany('App\TicketOrder', 'event_id', 'event_id');
}
I tried this in controller
here CreateEvent and Event is same. On my code i am using "CreateEvent" instead of "Event"
public function showMyTickets()
{
$user = Auth::user();
$ticket= $user->with('TicketOrder','TicketOrder.CreateEvents')->where('user_id',$user->user_id)->get();
dd($ticket);
}
this is what i got in dd($ticket)
the data are in relations. now i dont know how to retrive it and am i doing it correctly.
Collection {#1164 ▼
#items: array:1 [▼
0 => User {#970 ▼
#fillable: array:6 [▶]
#hidden: array:3 [▶]
#casts: array:1 [▶]
#connection: "mysql"
#table: "users"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:11 [▶]
#original: array:11 [▶]
#changes: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▼
"TicketOrder" => Collection {#1163 ▼
#items: array:1 [▼
0 => TicketOrder {#1068 ▼
#fillable: array:8 [▶]
#hidden: array:8 [▶]
#connection: "mysql"
#table: "ticket_orders"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:11 [▶]
#original: array:11 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▼
"CreateEvents" => CreateEvent {#1155 ▼
#fillable: array:22 [▶]
#hidden: array:1 [▶]
#connection: "mysql"
#table: "create_events"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:26 [▶]
#original: array:26 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#visible: []
#guarded: array:1 [▶]
}
]
#touches: []
+timestamps: true
#visible: []
#guarded: array:1 [▶]
}
]
}
]
#touches: []
+timestamps: true
#visible: []
#guarded: array:1 [▶]
#rememberTokenName: "remember_token"
}
]
}

Get object only when relation result is exist [laravel]

I have a problem with get data only when relation query count is more than 0.
This is my model of customer with relation
class Customer extends Model
{
protected $table = 'customers';
public function contracts()
{
return $this->hasMany('App\Contract');
}
This is my model of contracts
class Contract extends Model
{
public function customer()
{
return $this->belongsTo('App\Customer');
}
}
On the end i need only customers who they contracts beetwen some date
$customers = Customer::with(['contracts' => function($query)
{
$query->where('data_end','>=','2017-07-01')
->where('data_end','<=','2017-07-31')
->where('typ','=','U') ;
}
])->paginate(10);
But i have all customers. and it looks like this:
"Customer 1"
"Customer 2"
"Customer 3"
*"Contract 1"
*"Contract 2"
*"Contract 3"
"Customer 4"
*"Contract 1"
*"Contract 2"
*"Contract 3"
"Customer 4"
In this example i don't need customer 1,2, and 5. How can i do it with eager loading and object with relation on the end.
enter image description here
This is happen, i dont need customer with X on the screenshot - I mean, I don't need customer with 0 contracts from where query
-- Object from dd()--
end of this query
2 customer, 1st have 2 contracts, 2nd have 0 contracts
LengthAwarePaginator {#217 ▼
#total: 75000
#lastPage: 37500
#items: Collection {#213 ▼
#items: array:2 [▼
0 => Customer {#220 ▼
#table: "customers"
#connection: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:5 [▼
"id" => 1
"customer_number" => "46071600600"
"name" => "Nikodem Zalewski"
"customer_contact" => "507614445"
"customer_type" => "P"
]
#original: array:5 [▶]
#casts: []
#dates: []
#dateFormat: null
#appends: []
#events: []
#observables: []
#relations: array:1 [▼
"contracts" => Collection {#224 ▼
#items: array:2 [▼
0 => Contract {#227 ▼
#connection: null
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:10 [▶]
#original: array:10 [▶]
#casts: []
#dates: []
#dateFormat: null
#appends: []
#events: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [▶]
}
1 => Contract {#229 ▶}
]
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [▶]
}
1 => Customer {#221 ▼
#table: "customers"
#connection: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:5 [▶]
#original: array:5 [▼
"id" => 2
"customer_number" => "81050371854"
"name" => "Adam Wróbel"
"customer_contact" => "560047958"
"customer_type" => "P"
]
#casts: []
#dates: []
#dateFormat: null
#appends: []
#events: []
#observables: []
#relations: array:1 [▼
"contracts" => Collection {#222 ▼
#items: []
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [▶]
}
]
}
#perPage: 2
#currentPage: 1
#path: "*"
#query: []
#fragment: null
#pageName: "page"
}
You are almost there with your code.
You don't specify which version of Laravel you're using, but you should be looking at whereHas (This exists in Laravel since at least 5.0)
https://laravel.com/docs/5.0/eloquent#querying-relations (v5.0)
When accessing the records for a model, you may wish to limit your results based on the existence of a relationship. For example, you wish to pull all blog posts that have at least one comment. To do so, you may use the has method:
If you need even more power, you may use the whereHas and orWhereHas methods to put "where" conditions on your has queries:
Try the following code.
$customers = Customer::with('contracts')->whereHas('contracts', function($query)
{
$query->where('data_end','>=','2017-07-01')
->where('data_end','<=','2017-07-31')
->where('typ','=','U') ;
}
)->paginate(10);
This will load the contracts object with customers but only return customers who have contracts matching the query.

Laravel 5.4 return full order in blade

I have been struggling with Laravel relationships. I am making an simple webshop. I have 4 important tables: order, orderrule, product and user.
I have inserted the order with laravel Shoppingcart this all went well. But now I want to get the full order back again so I can make an PDF file for it.
This is my database design: https://i.stack.imgur.com/nfPJy.png
This is my order model:
public function orderRules()
{
return $this->hasMany(Order_rule::class, 'order_id', 'order_id');
}
public function locations()
{
return $this->belongsTo(Location::class, 'place_id');
}
public function users()
{
return $this->belongsTo(User::class, 'user_id');
}
This is my Controller function:
public function orders()
{
$user_id = Auth::id();
$orders = Order::with('orderRules')->with('locations')->with('users')->where('user_id', $user_id)->get();
dd($orders);
return view('orders', [
'orders' => $orders,
]);
}
And this is my result that I am getting from the dumpdata:
Collection {#239 ▼
#items: array:4 [▼
0 => Order {#224 ▶}
1 => Order {#225 ▶}
2 => Order {#226 ▼
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:5 [▶]
#original: array:5 [▶]
#casts: []
#dates: []
#dateFormat: null
#appends: []
#events: []
#observables: []
#relations: array:3 [▼
"orderRules" => Collection {#220 ▼
#items: array:2 [▼
0 => Order_rule {#244 ▼
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:5 [▶]
#original: array:5 [▼
"id" => 23
"order_id" => 521056
"product_id" => 1
"quantity" => 2
"date" => "2017-06-16 14:21:22"
]
#casts: []
#dates: []
#dateFormat: null
#appends: []
#events: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [▶]
}
1 => Order_rule {#245 ▶}
]
}
"locations" => Location {#233 ▶}
"users" => User {#219 ▶}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [▶]
}
3 => Order {#227 ▶}
]
}
I only want the name of the product via the orderRule table, but the orderRule join only gives the product_id. Can someone help me with this? Thanks in advance!
I would first add
protected $with = ['order', 'product'];
to your OrderRule model, that way the related order and produce information will always be eager loaded.
Then try this for pulling a user's orders:
$orders = Auth::user()->orders->with('locations')->get();
I wouldn't limit yourself to only the product name when retrieving orders also, it's not like the Product model is large and you may just need some of the additional data down the road.

Laravel trying to query relatinship model hasMany

I have the following tables in my application:
projects
projects_plot_types
Projects can have many plot types. I have the following relationship setup in the projects model.
/**
* The plot types that belong to the project.
*
* #return Object
*/
public function plotTypes()
{
return $this->hasMany('App\Models\Project\ProjectsPlotTypes');
}
I want to be able to get the plot type by querying it's name on the project model.
I have tried this, but it does not work:
$project->with('plotTypes')->whereHas('plotTypes', function ($query) use ($row) {
$query->where('name', $row->plot_name);
})->first()->plotTypes->first()->id;
Can someone point me in the right direction?
The output of $result as per below comment is:
Project {#705 ▼
#table: "projects"
#fillable: array:7 [▶]
+timestamps: true
#connection: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
#attributes: array:10 [▶]
#original: array:10 [▶]
#relations: array:1 [▼
"plotTypes" => Collection {#769 ▼
#items: array:1 [▼
0 => ProjectsPlotTypes {#774 ▼
#table: "projects_plot_types"
#fillable: array:2 [▶]
+timestamps: false
#connection: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
#attributes: array:4 [▼
"id" => "2"
"project_id" => "1"
"name" => "TYPE 3 - VENTILATION"
"budget" => "245.69"
]
#original: array:4 [▶]
#relations: []
#hidden: []
#visible: []
#appends: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
}
]
}
]
#hidden: []
#visible: []
#appends: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
}
You may also use join query like below
$result = Illuminate\Support\Facades\DB::table('projects')
->join('projects_plot_types', 'projects_plot_types.id', '=', 'projects.project_plot_id')
->where('projects_plot_types.name', '=', $row->plot_name)
->first();
print_r($result);
Maybe this is what you are looking for:
$result = $project->with(['plotTypes' => function($query) use ($row) {
return $query->where('name', $row->plot_name)->first();
}])->first();
dd($result); // print the result and die
UPDATE 1
Fetch the first item from the collection that has BelongsTo relationship:
$plotTypeResult = $result->plotTypes[0]->id;

Categories