I have the following table structure in my database:
products
id
product_formats
id
product_id
product_prices
id
product_format_id
When I'm trying to do $this->format->product; inside my ProductPrice class, I get an error:
LogicException: App\ProductPrice::product must return a relationship instance.
When I perform a dd inside my function:
dd($this->format()->first()->product);
I get the instance of the product. However, removing the dd would still throw the exception.
Why am I getting the LogicException?
ProductPrice
class ProductPrice extends Model
{
public function format()
{
return $this->belongsTo(ProductFormat::class, 'product_format_id');
}
public function product()
{
return $this->format->product;
}
}
ProductFormat
class ProductFormat extends Model
{
public function product()
{
return $this->belongsTo(Product::class);
}
}
Update
The result of dd($this->format); returns an instance of ProductFormat.
After investigating the HasAttributes::getRelationshipFromMethod(), I've noticed that if the property does not exist in the properties attribute of the class, it will try to retrieve a relation, hence the error.
To fix it, I had to add the following to my class:
protected $attributes = ['product'];
Otherwise, I could call product as a function instead of attribute:
$price->product();
Related
I am using Laravel/Passport and already can get data by id:
api.php/Controller.php
Route::get('members/{member}', 'MemberController#show');
public function show(Member $member)
{
return $member;
}
This just return all data by id, now I want to get member by phone number, so I created:
Route::get('members/{phone}', 'MemberController#phone');
public function phone(Member $member)
{
return $member;
}
Error:
exception:
"Symfony\Component\HttpKernel\Exception\NotFoundHttpException" file:
"C:\Users\xx\xx\xx\xx\vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\Handler.php"
line: 204 message: "No query results for model [App\Member]
2929292222"
route
Route::get('members/{phone}', 'MemberController#phone');
controller
public function phone(Member $member)
{
return $member;
}
Go to Member.php model
and add this method getRouteKeyName
public function getRouteKeyName()
{
return 'phone';
}
Laravel by default it will automatically inject the model instance that has an ID matching the corresponding value from the request URI.
If you would like model binding to use a database column other than id when retrieving a given model class, you may override the getRouteKeyName method on the Eloquent model:
for more information check the documentation
Hey i have three table like this
--table plan--
id
name
....
----table letter---
id
plan_id
....
---table person----
id
plan_id
name
.....
Model i have :
---Model plan---
class plan extends Model
{
protected $table = 'plan';
public function letter(){
return $this->hasOne('App\letter');
}
public function person(){
return $this->hasMany('App\person');
}
}
--Model person--
class person extends Model
{
public function plan(){
return $this->belongsTo('App\plan');
}
}
--Model letter--
class letter extends Model
{
public function plan(){
return $this->belongsTo('App\plan');
}
}
And in controller i write code like this :
$letter = letter::find($id) // $id from url parameter and it's work
return view('letter',['letter' => $letter]);
Nah in view i wanna acces person name from letter model as distinct , so i write code like this
{{ #foreach ($letter->plan()->person()->groupBy('name')->get) as $person }}
but it return error like this :
Call to undefined method Illuminate\Database\Query\Builder::person()
Where is my mistake(s)?
There is a difference between $letter->plan() and $letter->plan. If you call it like a method, Laravel will return the Query Builder. If you call it like an attribute Laravel will return the model from that relation.
So you're trying to call your model on the Query Builder, which is a method that doesn't exists and creates the error. This will fix your problem:
$letter->plan->person()->groupBy('name')->get()
In your controller you can do:
$letter = letter::find($id) // $id from url parameter and it's work
$persons = $letter->plan->person()->groupBy('name')->get();
return view('letter', compact('letter', 'persons'));
And in your view:
#foreach($persons as $person)
What i know:
$this->$parent->childs(); //we get childs data
what i want to know how:
$this->child->find($id)->parent(); //how to get childs parent without including model in controller | by just using eloquent
heres my sample code of employee and employeeDependent model:
trait EmployeeRelationships{
public function dependents(){
return $this->hasMany(\App\DB\EmployeeDependent\EmployeeDependent::class);
}
}
trait EmployeeDependentRelationships{
/**
* #return mixed
*/
public function employee(){
return $this->belongsTo(\App\DB\Employee\Employee::class, 'employee_id');
}
}
If you want to get the reverse of a BelongsTo relationship you need to specify the inverse of the relationship on the corresponding model. For example:
Employee Class
class Employee extends Model
{
public dependents()
{
return $this->hasMany(Dependant::class);
}
}
Dependent Class
class Dependent extends Model
{
public employee()
{
return $this->belongsTo(Employee::class, 'employee_id');
}
}
With these relationships defined you can then access the relevant models by calling the appropriate methods like so:
$dependents = Employee::first()->dependents; // Returns an eloquent collection
$employee = Dependent::first()->employee; // Returns a model of type Employee
Note that in this example using the first() method to grab a model, you can can do this with any object of the correct type.
Hi I'm using Laravel 4 and I have three models, Project (table name projects), Status (tables name: statuses) and AssignedProjectBoardStatus (table name: assigned_project_board_statuses). Now when I create a project statuses are automatically assigned if they are not selected from a list. The assigned_project_board_statuses table has two foreign keys the table schema is below:
id|project_id|status_id|order|created_at|updated_at
project_id and status_id are the foreign keys. Now I have a model as so:
app/models/AssignedProjectBoardStatus.php
class AssignedProjectBoardStatus extends AbstractModel {
public function projects() {
return $this->belongsTo('Project');
}
public function statuses() {
return $this->belongsTo('Status');
}
}
app/models/Project.php
class Project extends AbstractModel
{
public function assignedProjectBoardStatus() {
return $this->hasMany('AssignedProjectBoardStatus');
}
app/models/Status.php
class Status extends AbstractModel {
public function assignedProjectBoardStatus() {
return $this->hasMany('AssignedProjectBoardStatus');
}
There when I am fetching the projects and I want to see the statuses assigned I would call this as follows:
Project::assignedScrumBoardStatuses();
However this throws the following error:
Non-static method Project::assignedProjectBoardStatuses() should not be called statically, assuming $this from incompatible context
So I've changed the function as follows:
app/models/Project.php
class Project extends AbstractModel
{
public **static** function assignedProjectBoardStatus() {
return $this->hasMany('AssignedProjectBoardStatus');
}
However this then threw the following error:
Using $this when not in object context
So i then changed the function as follows:
public **static** function assignedScrumBoardStatuses() {
return **static::**hasMany('AssignedScrumBoardStatus');
}
And this then threw this error:
Non-static method Illuminate\Database\Eloquent\Model::hasMany() should not be called statically
Any ideas what I'm doing wrong and how I can get the assigned statuses from the model??
You can’t call Project::assignedScrumBoardStatuses() because when you do, the Project model doesn’t know which record you’re trying to fetch the assigned scrum board status for. It has no context.
Instead, find a record so you have a model instance, and you can then call your relation methods on that:
$project = Project::find($id)->assignedScrumBoardStatuses();
In Laravel 4.x I have a Customer Eloqeunt Model that has a relationship to a Customer_tel Eloquent Model:
class Customer extends Eloquent
{
public function tel()
{
return $this->hasMany('Customer_tel');
}
}
The Customer_tel table has a boolean column 'main'.
When I make an instance of the Customer Class in a view, then I can filter out the main number with the filter() method:
$Customer = Customer::find(1);
$Customer->tel->filter(function($tel)
{
if ($tel->main == true)
{
return true;
}
})->shift()->tel
But when I try to make a function in the class with the filter() method:
public function mainTel()
{
return $this->tel()->filter(function($tel)
{
if ($tel->main == true)
{
return true;
}
})->shift()->tel;
}
When I try to reference it in the view $Customer->mainTel, then it gives me an error "Call to undefined method Illuminate\Database\Query\Builder::filter()".
Why can't I filter the instance only outside of the class but not in the class? And is there a right way to do it?
Calling the method (tel()) returns the HasMany instance, upon which you can then call the query builder methods. Using Eloquent's magic properties, you can short-circuit it. So $customer->tel is equivalent to $customer->tel()->get(), which returns a collection. That is why it's working for you in your first example.
See the docs for more info.
A better option would be to do it in the query itself:
return $this->tel()->where('main', true)->pluck('tel');
Also note that you can create your own magic properties in Eloquent:
class Customer extends Eloquent {
public function tel()
{
return $this->hasMany('Customer_tel');
}
public function getMainTelAttribute()
{
return $this->tel()->where('main', true)->pluck('tel');
}
}
Now when you have a $customer model, you can call your magic method directly:
$tel = $customer::find(1)->main_tel;