Here is my problem. I have a table called news and table called categories, also I have a pivot table that connects these two called news_categories.
I am trying to fetch last 10 articles from certain category, but obviously pivot table doesn't have timestapms.
I was reading about hasMany(), belongToMany() but didn't find a good example of how it is done. Any help is appreciated
So far I have done this to News model:
public function categories(){
return $this->has_many_and_belongs_to("Categories")->withPivot('category_id', 'news_id');
}
But I have no idea how to select News based on pivot table value of category_id
You might want to read up on the Laravel 4 Eloquent Documentation a bit...
The relationship function is wrong and you don't need to specify the pivot items. The withTimestamps() function will automatically manage those on the pivot table for you.
public function categories()
{
return $this->belongsToMany('Category')->withTimestamps();
}
Related
In my app, you can create lists of roles that are attached to contacts. So you can assign the contact "Bob" the roles of "Gardener" and "Pet Sitter". Then you can create the list "People" and add "Gardener (Bob)" and "Pet Sitter (Bob)" to it.
I have the following tables:
contacts
id
name
roles
id
name
contact_role (pivot)
id
contact_id
role_id
lists
id
name
contact_role_list (pivot)
id
contact_role_id
list_id
Everything was working smoothly until the second pivot table linked to the first pivot table. My pivot tables are (currently) not having any models so I'm not sure if there is a built-in feature to tackle this in Laravel or if I need to think differently.
I currently have this in my List model:
public function list_roles(): BelongsToMany
{
return $this->belongsToMany(XYZ::class, 'contact_role_list', 'list_id', 'contact_role_id');
}
Is this even close? What do I put where it says XYZ::class?
Ok, so the below is doing what I want, but is there an even better way to do it? The key to solving my problem was to create a Model for ContactRole and changing extends Model to extends Pivot.
I placed this in my List Model:
public function list_roles(): BelongsToMany
{
return $this->belongsToMany(ContactRole::class, 'contact_role_list', 'list_id', 'contact_role_id');
}
And this in my ContactRole Model:
public function contact(): BelongsTo
{
return $this->belongsTo(Contact::class);
}
Now I could reach the contact data by using something like this: List::first()->contact_roles->first()->contact
Any way to use with, pivot or similar to tidy this up even more? Thanks!
I like to approach these issues in terms of Models rather than pivots. I think many new Developers in Laravel get over obsessed with what's going on in the Database which is fine, but theres a lot of Magic going on so you can write very simple code that does a lot of Heavy lifting, so that being said if I fully understand your problem
You have a Contacts Model
This model can have many roles
so in your contacts Model you need a role relationship
public function roles()
{
return $this->belongsToMany(Roles::class);
}
next of course you have a role Model (pun intended)
your each role can have many list
public function lists()
{
return $this->hasMany(List::class)
}
then the idea is now that you have roles on contacts and lists on roles you should be able to have many lists through contact
public function lists()
{
return $this->hasManyThrough(List::class, Role::class);
}
I've done similar things before and for your description it seems like that's the approach you might need to take.
I want to define a relationship between tables, and I don't know where I'm going wrong.
These are my tables:
users
-id
-email
-level
restaurants
-id
-name
-user_id
menus
-id
-name
restaurant_menu
-restaurant_id
-menu_id
-price
In the users table, the field level will set by me with two words: [user] or [restaurant].
User Model
public function restaurant(){
return $this->hasOne(Restaurant::class);
}
Restaurant Model
public function menus(){
return $this->hasMany(Menu::class);
}
Menu Model
public function restaurants(){
return $this->belongsTo(Restaurant::class);
}
I expect the output of this code:
$result = $restaurant->where('id',2)->menus()->get();
To be records and relations, but i get the following error.
BadMethodCallException
Call to undefined method Illuminate\Database\Eloquent\Builder::menus()
What should I do?
IN user model
public function restaurant(){
return $this->hasMany(Restaurant::class,'user_id','id');
}
Restaurant model
public function menus(){
return $this->hasMany(Menu::class,'id','menu_id');
}
Menu model
public function restaurants(){
return $this->belongsTo(Restaurant::class);
}
As you aspect your output you need to write
$result = Restaurant::with('menus')->where('id',2)->get();
you will get relational data. Like which restaurants has which menus.
You also can use this for your scenario. Use this in your Restaurant model
public function menues(){
return $this>hasManyThrough(Menu::class,restaurant_menu::class,'menu_id','id','id','restaurant_id');
}
Relations you define are not available for you in the query scope of your builder instance the way you tried to call them. They are available in the context of your models. Including your relationships in the queries is done differently - you should check official documentation on the matter first.
In your case, if you want to select all menus that belong to specific restaurant you have to ways:
You can first fetch specific restaurant and then get it's menus via a relationship:
$restaurant = Restaurant::find(2);
$menus = $restaurant->menus;
You can query for menus via Menu model:
$menus = Menu::whereHas('restaurants', function ($query) {
$query->where('id', 2);
})-get();
Also your relations are set up wrong. Based on table structure you've provided your menus and restaurants are in many-to-many relationship. Therefore restaurants() relation method in Menu class needs to return BelongsToMany instance. So while you're at it I would strongly suggest for you to go over relationships documentation and watch examples until you get the concepts of how different relationships work in Laravel.
Actually,
you defined relations in a correct way. I think that, you have an issue about to get those relations on the eloquent queries. If you want to get menu relation of a specific restaurant; you have to implement something like that.
$restaurant = Restaurants::find(2);
$restaurant->menus(); // this will return an array of related menus.
You should read Laravel Offical documentation. There are Retrieving The Relationship headlines for each relationship definition.
There is a problem with your relationship. You have a one to many relationship between restaurant model and menu model. However, your table structure suggests that, they have a many to many model.
If you think your model is right then change the menus table in following way,
menus
-id
-name
-restaurant_id //new field
Also, delete the "restaurant_menu" table.
If you think your database is correct then try changing the model accordingly.
I have a question, How i can relate two table in model function?
I want to relate between table stores and orders but i can't relate them..
can you help me please?
this is my stores table
and this is my orders table
Update
This is my code
public function order()
{
return $this->belongsTo(Order::class,'id','store_id');
}
I have pivot table and it has one to many relationship with another table, So I am confused with database design and relationship in Laravel Elequent.
Is this right way to design databse or should I create id as primary key for award_entries and use it is foreign key in entry_files. ?
If I am following existing design (first one), how will I write relation in Laravel eloquent?
Here how your relation will look like. You may need to change model or columns name.
In award_entry model:
public function entry_file() {
return $this->belongsTo('App\Models\entry_file','award_entries_award_id');
}
And in Entry_file model:
public function award_entries(){
return $this->hasMany('App\Models\award_entries','award_entries_award_id');
}
I have two tables in MySQL, where the first one is called users and the second one is called games. The table structure is as follows.
users
id (primary)
email
password
real_name
games
id (Primary)
user_one_id (foreign)
user_one_score
user_two_id (foreign)
user_two_score
My games table is holding two foreign relations to two users.
My question is how do I make the model relations for this table structure?? - According to the laravel documentation, I should make a function inside the model and bind it with its relations
for instance
public function users()
{
$this->belongsTo('game');
}
however I can't seem to find anything in the documentation telling me how to deal with two foreign keys. like in my table structure above.
I hope you can help me along the way here.
Thank you
A migration:
$table->integer('player1')->unsigned();
$table->foreign('player1')->references('id')->on('users')->onDelete('cascade');
$table->integer('player2')->unsigned();
$table->foreign('player2')->references('id')->on('users')->onDelete('cascade');
And a Model:
public function player1()
{
$this->belongsTo('Game', 'player1');
}
public function player2()
{
$this->belongsTo('Game', 'player2');
}
EDIT
changed 'game' to 'Game' as user deczo suggested.
Unfortunately the way you have this setup is not likely to work in the current context. You may have more luck with the belongsTo method, but again that only supports one relationship.
You could implement a user1() belongsTo, a user2() belongsTo and finally just declare a non eloquent function to return both (something like $users = array($this->user1(), $this->user2())