I got two tables (Models),
tags with id and name and
post_tag with post_id and tag_id.
How I can get from table tags name but with table post_tag post_id.
Look, you haven't given any code sample. But from your question, I guess that you've two model named, Tag & Post
So, your post_tag became the pivot table right. And it is a many-to-many relation.
In your Tag model build relation like,
public function postTag()
{
return $this->belongsToMany(Post::class, 'post_tag', 'tag_id', 'post_id');
}
In same way, in your Post model add a relation like
public function tags()
{
return $this->belongsToMany(Tag::class, 'post_tag', 'post_id', 'tag_id');
}
Now, your pivot relation is ready. At the time off attaching tags with Post, use $post->tags()->attach(Tag::find($tag)); // $post = new Post(); $tag is tag_id
To retrieve all post with associated tags, call
Post::with('tags')->get();
Similarly, to get tags associated with post
Tag::with('postTag')->get();
Head to laravel official website for many-to-many relations documentation
laravel One To Many Eloquent
Related
I am trying to show all posts of mine and my friends and also wanna show the comments on that posts
here is my controller
$user = Auth::user();
$friend_ids = $user->friends()->pluck('friend_id')->toArray();
$posts=PostModel::whereIn('users_id',$friend_ids)
->orWhere('users_id',Auth::user()->id)
->leftJoin('users as p_user','posts.users_id','=','p_user.id')
->leftJoin('post_comments','posts.id','=','post_comments.post_id')
->leftJoin('users as c_user','post_comments.friend_id','=','c_user.id')
-select('posts.caption','posts.image','posts.created_at','p_user.name','p_user.user_img as user_image','posts.id','c_user.user_img as commenter_img','post_comments.comment')
->get();
but the issue is that whenever any post have more than one comments it create more than one post and show one comment on any post , hope so you understand my question if not then I return my data here is the result
[{"id":5,"caption":"5thpost","image":"s1.jpg","name":"roger","user_image":"roger.jpg","commenter_img":"alex.jpg","comment":"nice one"},
{"id":5,"caption":"5thpost","image":"s1.jpg","name":"alex","user_image":"alex.jpg","commenter_img":"sufi.jpg","comment":"wow"}]
here you can see the id 5 is repeating I want to show all comments of id 5
You can go a step further and eager load from friends
$friends = $user->friends()->with(['posts.comments'])->get()
and you can chain on extra functions inside the with statement if required!
Likely you would want to add a between dates for the posts function for instance like:
$friends = $user->friends()->with(['posts' => function($q) use ($start, $end){
return $q->whereBetween('created_at', [$start, $end]);
},'posts.comments'])->get()
you can get the posts with $friends->posts and the comments with $friends->posts->comments and all the data you want will already be loaded and it stops N + 1 queries!
In Friends Model:
public function posts()
{
return $this->hasMany(Post::class);
}
In Post Model:
public function comments()
{
return $this->hasMany(Comments::class);
}
Don't use joins, use Model Relationships. Then you can eager-load related records like:
$posts = $postModel->with('comments')->where...
The result is that each Post Model within the Collection would have a nested attribute called 'comments', the name of the method within the Model that describes the relationship. And this 'comments' attribute would contain an Eloquent\Collection of Comment Model records.
I'm using Laravel and I'm trying to return this on API:
{
id: 1
name: BOM DIA
},
id: 2
name: BOM DIA (SUPERM VANEZA, BATISTA & IZEPE, BOM DIA)
}
But I'm confused. I have a table named 'Teams', and at this table, some columns have a number 'biid'. This 'biid' is the same information from another table name 'Clients'.
More than one 'Clients' can have same 'biid', but 'Teams' only have unique 'biid' or don't have any 'biid'.
I wanna to concat 'Teams' who has 'biid' with column named 'slug' in table 'Clients'.
Tables:
This should be like this:
How can I even think in make this?
Hello you need relations to do it if i know your problem
so let's talk about relation in your case Teams as many clients
the relation in your model teams will be this:
public function client(){
return $this->belongsToMany(Client::class);
}
What laravel does with belongsToMany method ?
for each client who as the same id's who you references teams and laravel will add it to you Eloquent Object.
Your client has one teams
soin your client model if you named it client :
public function team(){
return $this->belongsTo(Model::class);
}
to get the detail of relation who you need :
you will need to make the relations request, this will contribute to remove n +1 problem:
$clients = Client::with(['team']);
$teams = Team::with(['client']);
// here i don't know if you need ->get() try without and with
To access the relations:
foreach($clients as $client){
echo $client->team->name;
}
foreach($teams->client as $team){
echo $team->name;
}
// or
foreach($teams as $team){
echo $team->client->name;
}
But i think for that you need to rename you column because that are not explicit for laravel
to access relations you column need to have client_id and team_id to work.
Sometimes we use MySql Views to organize related tables to make it easier to search and sort. For example if you have Posts with a Status, and a Source.
Post
subject
body
source_id
status_id
Status
id
label
other_field
Source
id
label
other_field
View
create view read_only_posts as
SELECT statuses.label as status, sources.label as source, posts.*
from posts
left join statuses on statuses.id = posts.status_id
left join sources on sources.id = posts.source_id
Then we have the Post model and an extra model:
// Post.php
class Post extends Model
{
//
}
// ReadOnlyPost.php
class ReadOnlyPost extends Post
{
protected $table = 'read_only_posts';
}
This is nice because now you can directly sort or filter on Status or Source as a string not the id's. You can also include the 'other_field'.
But we have a problem that I need help with. If you have a polymorphic many-to-many relationship on Posts, I can't get it to work on the read only version. For example if you have polymorphic tags:
// Post.php Model
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
The problem is when you filter a post (using the read only model) with a specific tag you get sql like this:
select count(*) as aggregate from read_only_posts where exists (select * from tags inner join taggables on tags.id = taggables.taggable_id where read_only_posts.id = taggables.taggable_type and taggables.taggable_type = 'read_only_posts' and label = 'test')
As you can see the problem is the taggables.taggable_type = 'read_only_posts'.
I can't find a way to override the morph type for a model. (I am on laravel 5.4 and the MorphClass isn't there anymore). The morph map is an associative array so you can't do this:
// AppServiceProvider
public function boot()
{
Relation::morphMap([
'posts' => Post::class,
'posts' => ReadOnlyPost::class, <--- Can't do this
My stupid fix is when I attach a tag to a post I also attach it to ready_only_posts, which is kind of a mess.
Anyone else uses Views for read only models? Anyone have a better way to overriding the many to many polymorphic type for a specific model?
Looking at the code, I believe this might work.
class ReadOnlyPost extends Posts
{
public function getMorphClass() {
return 'posts';
}
}
In theory you should need to have the Posts model/table listed in the morph map, since the system will auto generate the type of "posts" for it based on naming.
Summary
I am building a music discovery service. My question is: How do I insert data into the three-way pivot table Tag_Track_User ?
Schema
I have this schema seen here at LaravelSD
It comprises of six main tables (and a few others):
Artists, Albums, Tracks, Tags, Users and Tag_Track_User
The Artists->Albums->Tracks relationship is straightforward and as you'd expect.
Tags, Tracks and Users all relate to one-another as no two can exist without the third.
Relationships
Artists hasMany() Albums
Albums hasMany() Tracks and belongsTo() an Artist
Tracks belongsTo() Albums
Tracks belongsToMany() Tags and belongsToMany() an Users
Tags belongsToMany() Tracks and belongsToMany() an Users
Users belongsToMany() Tags and belongsToMany() an Tracks
Models
User model
public function tags()
{
return $this->belongsToMany('Tag', 'tag_track_user', 'user_mdbid', 'tag_mdbid')->withPivot('track_mdbid');
}
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function tracks()
{
return $this->belongsToMany('Track', 'tag_track_user', 'user_mdbid', 'track_mdbid')->withPivot('tag_mdbid');
}
The Tag and Track model contain the same respective relationships.
Question
So my question is:
How do I insert data into the Tag_Track_User table? The tag_track_user table is a 3-way pivot table cointaining information about tracks that users have tagged.
You have to be logged in to tag a track (which means I have access to the user’s ID). The tracks ID is accessed as I am displaying it on the page where the form is contained. The tag on the other hand; if it already exists in the tags table, I want to get it’s ID and re-use that (as they are unique), if not, I want to create it, assign it an ID and insert that into the tag_track_user_table.
I need to check whether the Tag exists
If it does, get it's ID
Insert data into the Tag_Track_User table
Thank you
Any help I receive on this, is greatly appreciated.
Well:
$tag = Tag::firstOrCreate(array('text' => $tag_text));
TagTrackUser::create(array(
"tag_mdbid" => $tag->mdbid,
"track_mdbid" => $track->mdbid,
"user_mdbid" => Auth::user()->mdbid
));
Something like that? firstOrCreate does what the name says it does, the rest is pretty straightforward Eloquent.
Since seems that there is not an appropriate pattern in Laravel, the cleaner and easier way is to implement any three-pivot-relationships via a model dedicated to the pivot table:
class Track
public function trackTags()
{
return $this->hasMany('TagTrack');
}
...
class Tag
public function tagTracks()
{
return $this->hasMany('TagTrack');
}
...
class TagTrack
public function track()
{
return $this->belongsTo('Track');
}
public function tag()
{
return $this->belongsTo('Tag');
}
public function anotherRelationship(){
...
}
You can do:
$track->trackTags->myCustomPivotDataAndRelationship()
and in TagTrack you have freedom to add as many relationship and field I want
Note than you can still keep the many to many to use when you don't need to access pivot relationships
I have two tables:
tags
---
id
name
etc..
tags_synonyms
---
tag_id
syn_id
The syn_id is the synonym tag's id, and the tag_id reflects the "root" tag that will actually be used. The synonyms exist only to provide alternative spelling/etc for tags to reference and find the root tag through. (please correct me if they should be stored in a separate table)
So I created a model Tag in Yii, but I'm not sure how to setup the relationships for it.
What I want to be able to do is do:
$tag->synonyms, and $tag->root to grab all synonyms and the one root tag respectively.
How would I setup the relationships for these two things?
just check this link..to know more about how relationships are made in Yii Framework
http://www.yiiframework.com/doc/blog/1.1/en/post.model#customizing-x-16x-method
Relation should be declared in TagsSynonyms model
public function relations()
{
return array(
'synonymstags' => array(self::BELONGS_TO,'TagsSynonyms','tag_id'),
);
}
Relation should be declared in Tags model
public function relations()
{
return array(
'tags' => array(self::HAS_MANY, 'Tags', 'tag_id'),
);
}
I ended up just adding a linked_to root word column to the tags table and using that to reference the main word from the synonyms.