I have Author model that looks like this:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Author extends Model {
public $timestamps = false;
public function role()
{
return $this->hasOne('App\Role');
}
}
And Role model that looks like:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model {
public $timestamps = false;
}
My AuthorController.php looks like:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Author;
class AuthorController extends Controller
{
public function index(){
$role = Author::find(5)->role->pareigos;
return view('authors', ['role' => $role]);
}
}
But I get error like:
"SQLSTATE[42S22]: Column not found: 1054 Unknown column
'roles.author_id' in 'where clause' (SQL: select * from roles where
roles.author_id = 5 and roles.author_id is not null limit 1)
Where does the author_id even come from?
I have two tables in database, first one is authors that has id,firstname,lastname,role_id. Second one is roles that has two rows - id and pareigos. So I use this command:
$role = Author::find(5)->role->pareigos;
To find Author by id (5) and check his role_id in roles table and return pareigos if the ID's matches.
Don't know if I have described the problem clearly - if not, just let me know I eill add more details.
Your relationship is setup incorrectly. The table that has the key pointing to another table, belongs to that other table.
class Author ...
{
public function role()
{
return $this->belongsTo(Role::class);
}
...
This will want to look for a role_id key on authors table. By default, unless you pass more arguments to override it, Laravel uses the calling function name to decide the name of the foreign key for belongsTo relationships. [ method is named role, so it knows to look for role_id ... methodname + _id ]
Related
This is my tables structure:
Attribute.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Attribute extends Model
{
protected $guarded = [];
public function products()
{
return $this->belongsToMany('App\Product');
}
}
Product.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $guarded = [];
public function attributes()
{
return $this->belongsToMany('App\Attribute');
}
}
I want to get the value column for each row.
What code should I write in my controller to access this value?
Laravel version: 6.9.0
Thanks
You can solve this problem by adding the following method of your end of the relationship
withPivot(['value']);
public function attributes()
{
return $this->belongsToMany('App\Attribute')->withPivot(['value']);
}
And also
public function products()
{
return $this->belongsToMany('App\Product')->withPivot(['value']);
}
When we implements Many To Many relationship,it default create a intermediate table
In your case that table is attribute_product table, we might reference this table as Pivot
table.
This tables value was retrieve by those model by pivot attribute name as follows:
$product = App\Product::find(1);
foreach ($product->attributes as $attribute) {
echo $attribute->pivot->product_id;
}
To add Extra column in (Pivot table)
By default, only the model keys [$attribute_id,$product_id] will be present on the attribute_product table. If your pivot table contains extra attributes, you must specify them when defining the relationship:
return $this->belongsToMany('App\Attribute')->withPivot('column1', 'column2','value');
To change pivot Attribute Name to your given name
you may wish to rename your intermediate table accessor to values instead of pivot.
return $this->belongsToMany('App\Attribute')
->as('values')
Then you will retrieve by $attribute->values->product_id instead of $attribute->pivot->product_id
I have three relational table attached below.
https://drive.google.com/file/d/1q1kdURIwFXxHb2MgdRyBkE1e3DMug7r-/view?usp=sharing
I have also three separate models where defined relation among all of my table's.I can read the City Model's information from Country model using hasManyThrough() relation But cannot read the Country information from City model. I have tried to retrieve City model's using ``hasManyThrough``` but didn't get result (attached as commented country method ). Please read my model and it's relational method here..
Is there someone to help me for getting City model's information using Eloquent method hasManyThrough / hasManyThrough or using inverse of hasManyThrough / hasManyThrough ?
01.
<?php
namespace App\Hrm;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Country extends Model
{
//use SoftDeletes;
protected $fillable = ['name','description','status'];
public function districts(){
return $this->hasMany(District::class);
}
public function cities(){
return $this->hasManyThrough(City::class,District::class);
}
}
02.
<?php
namespace App\Hrm;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class District extends Model
{
//use SoftDeletes;
protected $fillable = ['country_id','name','description','status'];
public function country(){
return $this->belongsTo(Country::class);
}
public function cities(){
return $this->hasMany(City::class);
}
}
3.
namespace App\Hrm;
use App\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class City extends Model
{
//use SoftDeletes;
protected $fillable = ['district_id','name','description','status'];
public function district(){
return $this->belongsTo(District::class);
}
// public function country(){
// return $this->hasOneThrough(Country::class, District::class);
// }
Doesn't look like there is a native way to define the inverse of a "hasManyThrough" relationship yet in Laravel. There have been a few issues opened on github to request it, but they were closed.
You could use the staudenmeir/belongs-to-through package if you don't mind installing a third-party package for this functionality. Then you should be able to define a belongsToThrough relationship like this:
class City extends Model
{
use \Znck\Eloquent\Traits\BelongsToThrough;
public function country() {
return $this->belongsToThrough(Country::class, District::class);
}
}
Why can't use parent method?
$city = City::find(1);
$country = $city->district->country();
i just had a similar situation i was able to accomplish a belongsToThrough with hasOneThrough
public function country()
{
return $this->hasOneThrough(
Country::class, // model we are trying to get
District::class, // model we have an _id to
'id', // WHERE `district`.`id` = `city`.`district_id`
'id', // `countries`.`id`
'district_id', // local column relation to our through class
'country_id' // `district`.`country_id`
);
}
what this should generate is
SELECT * FROM `countries`
INNER JOIN `districts`
ON `districts`.`country_id` = `countries`.`id`
WHERE `districts`.`id` = ?
-- ? == city.district_id
Database structure:
City:
id: increments
district_id: integer
...
Country:
id: increments
...
District:
id: increments
country_id: integer
...
we can then do $city->country
note: i have not fully tested this but with the testing that i have done it 'works'
Edit: i originally thought that i needed to leave the localKey
parameter null otherwise the relation wont work. it turns out i didnt
fully understand what that column was doing and that was wrong. That
key is the local column that relates to our through column (unless i
still have more to learn/figure out), when left the value as null, it
would use the local id column which a. is the wrong value, b. can also
be out of range (which is how i discovered it was using the wrong
value)
in my testing i only had two rows, both with the same relations. what
i didnt realize though was that on the "through table" both row 1 and
2 and the same related (relation where are trying to reach) so i didnt
notice the issue right away. hopefully now its all working
I am new to Laravel and also asked the question on Laracast without any success so far.
Here is my problem: I have a database layout something like this:
Table: categoryA_products
Table: categoryB_products
Table: categoryC_products
and per default the Laravel user table:
Table: user
I have create a two Laravel Eloquent models:
Product:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
// protected $table = '';
public function users()
{
return $this->belongsTo( User::class );
}
}
User:
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function products()
{
return $this->hasMany( Product::class );
}
}
As each product has a different table name I would normally create 1 model for each table but as they are all similar I would like to define the model table name at runtime.
I know I can do this with "$product->setTable()" but as I use the "newRelatedInstance" class from Laravel (hasMany and belongsTo) I cannot initiate the product class and set the table.
Is there a workaround for this?
Yes, I am aware that I could create a category table and link the products to each category but this is a fictional database model. There is a reason for this approach and I can explain it more in detail if needed. That said it make sense for this sample but I cannot use it for the live database.
I have a working solution with a model for each "category" but this is very messy.
Any help would be appreciated.
Since you're unable to load the relations, you could try referencing and re-initializing them like:
$relations = $product->getEagerLoads();
$attributes = $product->getOriginal();
table_name = 'categoryA_products'; // or categoryB_products or categoryC_products
$product->newQuery()
->newModelInstance($attributes)
->setTable($table_name)
->setEagerLoads($relations)
->...
I have a model
Education.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Education extends Model
{
public $timestamps = FALSE;
public function Member(){
return $this->belongsTo('App\Member');
}
}
In database i have a table named educations
In controller when I'm trying to access the data of the educations table through App\Education model I'm getting this error
QueryException in Connection.php line 770: SQLSTATE[42S02]: Base table
or view not found: 1146 Table 'dsse.education' doesn't exist (SQL:
select * from education)
Why laravel is searching for education table in the database where it should search for educations table. What is the problem?
here is the controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Member as Member;
use App\Education as Education;
class memberController extends Controller
{
public function addMember(){
$education = Education::all();
var_dump($education);
}
}
Add this to your model. You may set any custom table name as follow
protected $table = 'educations';
I had the same problem before,
and yes it is a solution to add
protected $table = 'educations';
but the problem is because laravel uses a class called
Illuminate\Support\Pluralizer
inside
Illuminate\Support\Str
and this class is not just adding "s" at the end of words or ies...
it is real pluralizer and education is an uncountable word, so is information...
so you need to add $table to your model.
I have two tables like below:
users table:
id - fname - lname
users_projects table:
id - user_id - title
my models are inside a directory called Models:
Users model :
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Users extends Model
{
//
public function usersProjects()
{
return $this->belongsTo(UsersProjects::class);
}
}
UsersProjects model:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class UsersProjects extends Model
{
protected $table = 'users_projects';
//
public function users()
{
return $this->hasOne(Users::class);
}
}
now, I want to show last projects :
$projects = UsersProjects::limit(10)->offset(0)->get();
var_dump($projects);
return;
but my var_dump shows last projects ! I want to have fname and lname ! where is my wrong ?
I think you may have your relationships set up a little wrong. If a user can have more than one project, in your user model ...
public function usersProjects()
{
return $this->hasMany(UsersProjects::class);
}
You might want to use a little simpler naming too ...
public function Projects()
{
return $this->hasMany(UserProject::class);
}
(or simply Project if you don't have any other "Project" models)
The in your "Project" class ...
public function User()
{
return $this->belongsTo(User::class);
}
(assuming you rename your model to User instead of "Users". Your table name should be "users" but a model is by nature a singular object. So it's appropriate to call it "User" - and your UsersProjects model should just be UserProject or just Project)
Now if you call the method something other than "User" you will have to add the foreign key name ...
public function SomeOtherName()
{
return $this->belongsTo(User::class, 'user_id');
}
Then ...
$projects = Project::with('User')->limit(10)->offset(0)->get();
Will return a collection of projects with the User eager-loaded. (assuming you have renamed your UsersProjects model to "Project")
#foreach($projects as $project)
...
First Name: {{ $project->User->fname }}
...
#endforeach
Could you specify the relationships between the tables? (one to one, one to many) at first sight, I think that the relations are wrong