Laravel relationships - php

Trying to figure what table I need to make this relationship to work...
I'd like the user to mark a post as favorite and save it so when he log back in, he can view all his favorite posts.
So I have User and Post models and their relationships of course.
User hasMany Post, Post belongTo User
Do I need to add Favorite model and add fav_id to both User and Post models ?
Or maybe adding pivot table?

If a favorite is defined as a simple relationship between users and posts, you don't need a model for it. However, you do want a pivot table, call it something like favorites. It would contain id, post_id, user_id, created_at, updated_at.
Then in your user model:
public function favoritePosts()
{
return $this->belongsToMany('Post', 'favorites');
}
And in the post model:
public function favoritedBy()
{
return $this->belongsToMany('User', 'favorites');
}
So now, for any given user, you can do $user->favoritePosts to get an array of posts that user has "favorited".
And from a post object, you can do $post->favoritedBy, to get an array of users that have favorited that post.
I haven't tested this but that seems like that would work off the top of my head.

Related

How to check if some post is liked by User in laravel

I have posts, users and favorites table.
For example, I make some post favorited for a user with an id of 3 like this :
User::find(3)->favorites()->attach($post->id);
and if users send request twice it will insert this favorite with this post_id, user_id twice.
I want to check if a post is not liked by this user, then save record in the database.
or if a post is favorited then unfavorite it.
how can I do this with eloquent relationship ??
I have User, Post models.
You could use toggle():
User::find(3)->favorites()->toggle($post->id);
This would like it if it not liked, and unlike it if it is.
If you just want the function not to duplicate likes in the table, just use syncWithoutDetaching:
User::find(3)->favorites()->syncWithoutDetaching([$post->id]);
Putting this on your User model:
class User extends Model {
public function like($postId){
$this->favorites()->syncWithoutDetaching([$post->id]);
}
public function unlike($postId){
$this->favorites()->detach([$post->id]);
}
}

How to retrieve data from additional columns in a pivot table and also be able to update it in laravel 5.2

I was working on making a group functionality for my website which uses a many to many relationship between groups and users.
My User model looks like this:
public function groups(){
return $this->belongsToMany('App\Group')->withPivot('role')->withTimestamps();
}
My Groups model looks like this:
public function users(){
return $this->belongsToMany('App\User')->withPivot('role')->withTimestamps();
}
So my third column has the name of role which is a string variable and is set to a default of "member" for members of my group and I set it to "admin" for the actual user who creates a new group. But I want the admin to have the option of making multiple members admins as well which would require me to check weather the current current user who sent the request is an admin or not. If he is, then I wanna be able to take his request of making a member an admin which would require me to update the role for that particular "member" to an "admin".
In the laravel documentation it only shows you how to attach and detach data in a pivot table and else where I have only seen methods of retrieving data from the first two columns but how can I do the same for additional columns and also be able to update it using the updateExistingPivot method?
You could access the column simply using pivot e.g :
$user->pivot->role
Take a look at Retrieving Intermediate Table Columns in documentation Eloquent Relationships.
Hope this helps.

Linking a Model (ie. comment) to many other Models (ie. post, profile)

I am building a PHP application with Laravel where I have a Comment Model and many other models to which Comment can be attached to.
For example, a Profile can have many Comment but also a Post can have many Comment.
Should I split Comment in two models (ProfileComment and PostComment) or should I keep them together like this?
class Comment {
public function user()
{
return $this->hasOne('User');
}
public function profile()
{
return $this->belongsTo('Profile');
}
public function post()
{
return $this->belongsTo('Post');
}
}
If I keep them together, then on a database level how should I manage the comments table?
I was thinking about having the following columns:
integer: id - auto-incrementing id
integer: user_id - the user id
integer: foreign_id - profile/post id
varchar: type - which model? profile or post?
varchar: content - the actual comment
Is this the wrong approach?
if you want to use 1 table you will need to make Comment model morph.
if you don't want to use morph, make separated.
I think if you will use schema from your question, you will use morph.
I don't tkink where is need to make more tables, because all comments will have same structure (id, user_id (author), comment)
so in this case you will need just to make it morph (tagable).

Laravel 4 Eloquent select

I have 3 tables
--- Posts (all the posts)
rows = id, title, content
--- Boards (all the boards)
rows = id, title
--- board_post (the link between boards and posts: many <-> many)
rows = board_id, post_id
2 Eloquent classes named board and post
now I would love to select all the posts from a board, based on board_post
I was thinking in the way of:
Posts::whereIn('id', $board->post_ids())
how would I be able to do this, that first off
that if I do Board::find(1)->post_ids I get all the post id's of that board
And then how wuld I be able to get all the post opbjects from that?
greetings Glenn
Why are you using a many-to-many relationship for Posts and Boards? It would most likely be a one-to-many relationship: A Board may have several posts, but a Post should only belong to one board (this would simplify your database structure to remove the board_post table).
You would then do:
Inside of Board class:
public function posts() {
return $this->hasMany('Post', 'board_id');
}
Then, Board::find(1)->posts would get you all of the posts for that board (use posts, not posts()).
To do it with your current database setup, use belongsToMany instead:
public function posts() {
return $this->belongsToMany('Post', 'board_post');
}
If you want to load a Board WITH all of it's posts (eager-loading) use this:
Board::with('posts')->find(1)
Otherwise, just to get the posts for a particular board, use:
Board::find(1)->posts
In Board model make sure you define belongsToMany relationship
public function posts()
{
return $this->belongsToMany('Post', 'board_post');
}
Now you should be able to do this:
Board::find({id})->posts
Forther reading material: http://laravel.com/docs/eloquent#relationships

Retrieving user posts

how can I pull all the posts of a certain user? should i foreach all the posts of a certain user? Like if user1 posted something and I want to pull out whatever he posted and only shows when he's logged in.
In Laravel, if you are using Eloquent relationships things would look something like this.
First, define your relationships within your models. If you're following the example below, I'm going to assume the following.
Your users table in database is named users. Your posts table in
database is named posts, and has an integer column named user_id
corresponding to the id of the user the post belongs to. If your
table and column names are different, make sure you read the Laravel
docs to learn how to set custom table names and column names for
Eloquent models.
app/models/User.php
<?php
class User extends Eloquent {
// All the default User.php stuff....
public function posts()
{
return $this->hasMany('Post');
}
}
app/models/Post.php
class Post extends Eloquent {
public function user()
{
return $this->belongsTo('User');
}
}
After we've defined those relationships, you can get a particular user using something like this.
$user = User::find(1); // This will get the user with an ID of one.
Then, you retrieve that user's posts, we can use the Eloquent relationship we defined earlier.
$posts = $user->posts()->all();
If the user is already logged in, you can user the Auth class to do this for the logged in user.
$posts = Auth::user()->posts()->all();
You'll now realize that ->posts() actually returns a Collection, and you can use all of the Query and Eloquent methods on that collection as normal.

Categories