I am just starting with ORM. I had a question, this is my tabel --
table a - (aid, aname, atag);
table b - (bid, aid, bname, .. );
It is One to Many relationship - that is One aid can belong to many bid but one bid can belong to only one aid.
So I was trying out this code, In the out put I want -- (bname,aname) for all the records.
A model --
class A extends Eloquent {
protected $table = 'a';
protected $primaryKey = 'aid';
public function brelation() {
$this->belongsToMany('B','aid');
}
}
B model --
class B extends Eloquent {
protected $table = 'b';
protected $primaryKey = 'bid';
public function getANames() {
$this->hasOne('A','aid');
}
}
In Controller --
foreach(B::with('getANames')->get() as $b_item){
echo $b_item->bname." , ".$b_item->aname;
}
Couple of points to clarify --
1) I have to specify the foreign key to make sure they map. Because in my actual case they are named differently.
2) I am using Laravel 4.
Can someone show me what I did wrong and how I can get the desired result.
===== Update =====
class A extends Eloquent {
protected $table = 'a';
protected $primaryKey = 'aid';
public function brelation() {
$this->belongsTo('B','aid');
}
}
I still cannot access the aname column i.e ($b_item->aname) in the controller.
A couple of things you should be aware of:
If you have a custom primary key, you need to set the $primaryKey property on your eloquent models to the primary keys you have in the DB.
You can't mix and match belongsToMany relationships with anything other than belongsToManys. A belongsToMany is exclusively for the case where you have two tables that are connected by a pivot table. In your case, B belongsTo A, and A hasMany B.
Related
I've just started using Eloquent ORM (Without Laravel) and I am having issues with the many to many relationships.
I have a table where I store Families (Article categories), another one for the Articles, and a third one as a "pivot". I want to be able to get all the articles a Family has, and all the families an article belongs to. So I have coded this models.
Families
class Families extends Model {
public $table = 'Families';
public function Articles() {
return $this->belongsToMany('Articles', 'articles_families', 'families_id', 'articles_id');
}
}
Articles
class Articles extends Model {
public $table = 'Articles';
public function Families() {
return $this->belongsToMany('Families', null, 'articles_id', 'families_id');
}
}
Then I am trying to retrieve the data like this:
$families = Families::all();
echo $families[1]->Articles;
However, it just returns an empty array, when it should return a couple of articles. I have tripled checked that all the values are correct in the three tables. If I echo the Eloquent query debugger I can see that it is looking for a null value and I'm pretty sure that's the problem, but I don't quite know how to fix it. Here:
{"query":"select * from `Families`","bindings":[],"time":49.13},{"query":"select `Articles`.*, `articles_families`.`families_id` as `pivot_families_id`, `articles_families`.`articles_id` as `pivot_articles_id` from `Articles` inner join `articles_families` on `Articles`.`id` = `articles_families`.`articles_id` where `articles_families`.`families_id` is null","bindings":[],"time":38.93}
The null value is at the end of the last query.
I just found the solution myself. As my primary key columns are called Id, and Eloquent by default assumes the primary key is called id, I needed to override that by adding a class property protected $primaryKey = "Id"; and it now retrieves the data properly.
I am want to update my records in my database using Eloquent model. I am having an error in updating user_profile table that saying where id is not null.
User Model
class User extends Model
{
public function profile()
{
return $this->hasOne('App\Models\Common\UserProfile');
}
}
UserProfile Model
class UserProfile extends Model
{
public function user()
{
return $this->belongsTo('\App\Models\User');
}
}
Controller
$user->fill($data);
$user->save();
$user->profile->fill($data);
$user->profile->save();
In MySQL query it looks like this:
UPDATE users, user_profiles
SET users.name='Test Name',
user_profiles.email='test#gmail.com'
WHERE users.id=1
AND user_profiles.user_id=1;
I know MySQL query but I'm new to Eloquent and I want to do it in Eloquent model. Maybe there are some in here that can provide an explanation on how the magic works in Eloquent.
By default eloquent assumes, that any model has an id column as primary key. If that is not the case, you need to "register" the primary key with
protected $primaryKey = 'user_id';
in the model class.
I have made two tables Inventories and Inventory_images. Primary key of Inventory table is the foreign key of inventory_images table now i am trying to fetch all the images of same inventory but getting error.
Here's my code
Inventory Model:
/**
* The table name that should be hidden from other modules
*/
protected $table = 'inventories';
protected $PrimaryKey = 'id';
public function test(){
return $this->belongsTo('App\InventoryImage', 'i_id');
}
InventoryImage Model:
protected $table = 'inventory_images';
protected $PrimaryKey = 'id';
public function inv_det(){
return $this->belongsTo('App\Inventory', 'id');
}
Controller:
$inventory = Inventory::with('test')->orderBy('id', 'DESC')->paginate('10');
dd($inventory);
Can some one please help me find out the issue
You are making some mistakes in your code which you should resolve first (and which might help you solve your problem).
First, the variable name to overwrite the primary key should be $primaryKey and not $PrimaryKey (variable names normally always start with a small letter.
This should not have any influence though, since Laravel assumes the primary key field to be named id anyway.
More importantly, you are in both cases using the belongsTo method, although in one case it should be hasMany. In a 1-n relation the parent model should return the hasMany relationship, and the child model (which holds the column with the foreign key) the belongsTo.
Furthermore, the second argument of the hasMany or belongsTo method is the foreign key column name, in case it is different of the snake case representation of the model (appended by _id). So IF your inventory_images table has a differently named foreign key column other than inventory_id, you need to pass along the second argument with the correct name. I assume that your foreign key name is i_id, so you need to pass it to both functions.
https://laravel.com/docs/5.4/eloquent-relationships#one-to-many
Please check if this works:
/**
* The table name that should be hidden from other modules
*/
protected $table = 'inventories';
protected $primaryKey = 'id';
public function test(){
return $this->hasMany('App\InventoryImage', 'i_id');
}
And the child table:
protected $table = 'inventory_images';
protected $primaryKey = 'id';
public function inv_det(){
return $this->belongsTo('App\Inventory', 'i_id');
}
I have two models User and UserType declared as follows:
class User extends Model {
protected $table = 'user';
protected $primaryKey = 'user_id';
public function company() {
return $this->hasOne('App\Models\Company', 'company_id', 'company_id');
}
public function userType() {
return $this->hasOne('App\Models\UserType', 'user_type_id', 'user_type_id');
}
}
class UserType extends Model {
protected $table = 'user_type';
protected $primaryKey = 'user_type_id';
}
Now, I query the relationships using:
User::with('userType', 'company')->all()
Strangely, I get the company but userType is always null.
The MySQL query log shows that Laravel was able to get the user_type record.
The only difference between company and userType relationships are the data type of the primary keys. company.company_id is numeric while user_type.user_type_id is a string.
I think it is related to the data type of the keys however, I have a similar setup on Laravel 5.1 and it runs perfectly.
Laravel supports non-numeric primary keys but you need to set:
public $incrementing = false;
on your model class.
I corrected the issue by changing UserType definition to:
class UserType extends Model {
protected $table = 'user_type';
protected $primaryKey = 'user_type_id';
public $incrementing = false;
}
The first issue i notice with your relationship is that the first user_type_id you have passed to the hasOne function is wrong because you have the user_type_id as the primary key of the user_type table. The second argument of the hasone must be the foreign key of the parent table which is the user. So if you have anything like user_id in the user_type table use that instead.
But if thats not the case and user rather belongs to UserType then you have to change the hasOne to belongsTo.
Eager Loading uses Primary Keys from the parent table inside the IN(...) clause, as clearly stated in Laravel's documentation:
select * from books
select * from authors where book_id in (1, 2, 3, 4, 5, ...)
Is it possible not to use the Primary Key for this, but another key from the books table? Or even a key retrieved from a pivot table?
Yeah we can do eager loading on non-primary columns. For this you need to define db-data relationships in models:-
Define your models Book & Author like this:-
class Books extends Eloquent {
public static $table = 'books';
public function bookauthors(){
return $this->has_many('authors','book_id');
}
}
class Authors extends Eloquent {
public static $table = 'authors';
public function books()
{
return $this->belongs_to('books','book_id');
}
}
Now you can use following line of code to eager load books with authors on a key "book_id":-
$books = Books::with(array('bookauthors'))->get();
I hope this helps you...i haven't tested on my local or test db. But had used similar eager loading for posts-tags relationship.