Laravel 4 - save tags - laravel

I have 3 tables:
posts => id, title, body, ...
tags => id, name, count
post_tag => post_id, tag_id
Post model has
public function tags() {
return $this->belongsToMany('Tag');
}
Tag model has
public function posts() {
return $this->belongsToMany('Post');
}
Selecting is working, but I want insert to DB
If new tag - insert to tags
Insert relation to post_tag
Increase tag count
For now I have
$post = new Post;
$post->title = Input::post('title');
$post->body = Input::post('body');
$post->save();
I have tags separated with ,. For example javascript, jquery, ajax.
How to do it? Explode tags and then check every tag if exist and then do 2 inserts (to tags and post_tag) or is there "magic" solution?

Have a look to this, it'll probably help you
Inserting related models
I think the function you need is attach. I've never used but I believe it's what you need. Have a look ;)

Related

Route model binding select specific columns with relation

Route:
Route::get('/posts/{post}', [PostController::class, 'show']);
Controller:
public function show(Post $post){
$postData = $post->load(['author' => function($query){
$query->select('post_id', 'name');
}])
->get(['title', 'desc', 'created_date'])
->toArray();
}
This returns all the posts in the database, While I only want to get the selected post passed to the show function.
So if I visit /posts/3, It should show data related to the post with id = 3, not all posts.
The result should be an array with only the selected post.
When you are inside the Controller you already have the Post you want. If you call get you are getting all posts with a new query.
To select specific columns from a relationship, you can do it like this:
public function show(Post $post)
{
$post->load('author:id,name,age'); // load columns id, name, age from author
}
Notice that including the id is required.
To specify columns for the Post, there's no way to do it per route, the only way is to override how Laravel resolves the implicit binding. For that, you can add this in your Post model class:
public function resolveRouteBinding($value, $field = null)
{
return $this->whereKey($value)->select(['id', 'body', 'author_id'])->firstOrFail();
}
Notice that including the author_id is required to load the Author afterwards inside the Controller method. Also keep in mind this will affect all routes where you implicitly load a Post.
Please don't use get() function on the model.
public function show(Post $post)
{
$post->load(['author' => function ($query) {
$query->select(['post_id', 'name']);
]);
dd($post->toArray());
}
Btw, the author shouldn't have a post_id, because author can have multiple posts. you should update the database structure or you are doing wrong in the controller. (my bad, Thanks #techno)

How to create data into junction table many to many relationship without create data into the junction point to

It inserts both table inside tags and tagables, what i want is just to insert into tagables ( junction ) table. Cause before it insert into tagables, theres code to check first if tag will insert into tags table already exist or not, if exist just grab the id. To make it simple to my problem. i just don't include code to check if tags is exist or not.
post model
public function tags(){ return $this->morphToMany( Tag::class, 'tagable', 'tagables', null, 'tag_id ); }
post controller
// tags table theres a row id 1 with name greeting
$post = Post::create( ['body' => 'Hello World'] );
$post->tags()->create( ['tag_id' => 1] );
Tables
// posts table
$table->mediumIncrements('post_id');
$table->string('body');
// tags table
$table->mediumIncrements('tag_id');
$table->string('tag_name');
//tagables table
$table->unsignedMediumInteger('tag_id');
$table->unsignedMediumInteger('tagable_id');
$table->string('tagable_type');
I think the simplest way do this to start by creating the tag with the eloquent method 'firstOrCreate', and then when you already have a new tag or existing tag you can add this tag to a new Post. The code may look like something like this:
class Tag extends Model
{
protected $guarded = [];
public function posts()
{
return $this->morphedByMany(Post::class, 'taggable');
}
}
$tag = Tag::firstOrCreate(
['tag_name' => 'traveling'],
);
$post = $tag->posts()->create([
'body' => 'My new interesting post',
]);

Laravel Relationships - Select rows with same column value in blade

Let's say I have a post with many comments and I properly defined $post->comments relation in my post model. Comments have a column named confirmed with the value of 0 or 1. How can I select confirmed (rows which have confirmed value of 1) rows in my blade template?
This can help you
In your Post model
public function comments()
{
return $this->hasMany(Comment:class);
}
public function confirmedComments()
{
return $this->comments()->whereConfirmed(1);
}
And from your controller
$comments = $post->confirmedComments;
If in blade, you want select confirmed comments, it's so easy to do it with
#if($comment->confirmed)
//confirmed comment
#else
//
#endif
Hope it'll be helpful !
There are many ways to do this.
If you already have the comments eager loaded, then you can use the where() method on the comments collection:
$confirmedComments = $post->comments->where('confirmed', 1);
This will go through all the comments in the collection and only return those that are confirmed.
If you don't have the existing collection, you can add the where clause to the relationship query. This way, you're only getting confirmed comments from the database, and you're not wasting resources retrieving and building models for comments you're not using
$confirmedComments = $post->comments()->where('confirmed', 1)->get();
And, another option, would be to create a new relationship for just confirmed comments, and that way you can eager load the new relationship:
public function comments()
{
return $this->hasMany(Comments::class);
}
public function confirmedComments()
{
return $this->comments()->where('confirmed', 1);
}
$confirmedComments = $post->confirmedComments;

Fetch pivot table data in laravel 4.2

I have created a pivot table post_tag and inserting data into it using sync method.
Now I want to fetch respective tags of a post to show in the view like following
{{ $post->tags }}
How can I do this? Thanks in advance.
You have to convert your object to array. In laravel, you can use like this.
{{ $post->tags->toArray() }}
For more detail in documentation.
Edit
In your Post model.
public function tags()
{
return $this->hasMany('Tag'); // One to Many
return $this->belongsToMany('Tag'); // Many to many
}
You can get like this.
$tags = Post::find($postId)->tags;
Or
$post = Post::find($postId);
$tags = $post->tags;
Hope it will be work for you.

Laravel 4.2 Eloquent query by relationship column value

Good day to you all...
I'm trying to access a collection based on a column in a related table within Eloquent (Laravel 4.2).
I have the following tables:
tags:
(int) id
(string) name
tag_usage:
(int) id
(string) model (the name of the model that is allowed to use the tag)
tag_tag_usage: (pivot)
(int) id
(int) tag_id
(int) tag_usage_id
I also have a taggables (polymorphic to store tags for multiple models) table which I believe is out of scope here as I only want to retrieve the tags that am allowed to use for each model.
My tag model has the relationship
public function usage()
{
return $this->belongsToMany('TagUsage');
}
and the TagUsage model has
public function tags() {
return $this->belongsToMany('Tag');
}
Now, what I want to do is return the tags that ONLY have a specific usage, some pseudo code would be
get_tags->where(tag_usage.model = modelname)
which would return only a subset of the tags.
Tried a few things with no success so over to the many fine brains available here.
Many thanks.
You need to use whereHas in the following way:
$tags = Tag::whereHas('usage', function($q)
{
$q->whereModel('modelname');
})->get();

Resources