Laravel 4 Eloquent select - php

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

Related

Laravel child relationship from the same table alias issue

I have 2 tables structured as such:
videos table
id
comments table
id
commentable_id
commentable_type
text
And each has their own model.
Video has the following relationship to comment:
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
Here's where it get's a bit interesting though, because comments can have comments under them at 1 level, so a top level comment can contain any number of child replies but the children cannot have replies on them.
That is represented by the following relationship on the Comment model:
public function replies()
{
return $this->morphMany(__CLASS__, 'commentable');
}
The problem
I need to now sort these by a combined sum between the comment AND comment replies count.
I've tried adding a hasManyThrough relationship on the parent (Video) model but that ends up failing because the table isn't aliased (since there are technically comments through comments to get to replies).
How would I represent this relationship in laravel on the video model? What I've tried seems fruitless
SQL
I thought maybe writing out the SQL might help, but since Laravel doesn't seem to alias table names, it seems almost impossible to convert this into a provided laravel relationship
SELECT replies.*
FROM comments
RIGHT JOIN comments AS `replies`
ON `replies`.commentable_id = `comments`.id AND `replies`.commentable_type = 'comment'
WHERE `comments`.commentable_id = 'VIDEO ID'
AND `comments`.commentable_type = 'video';

Laravel Eloquent Relation between 3 table

I need some help make a music library database.
I have 3 tables albums, artists, roles
I want an artist to have a role for each album.
like :
artist 1 work as Composer for album 1, but also work as arranger on album 2 or work as composer and arranger on album 3
I have tried this
how should database looks? and what type relationship is?
In your current schema, you will not be able to tag the role of the artist on basis of album.
As there is no relation in your tables to define that the entry in artist_role table is for specific album. So, what I would suggest is to create an intermediate table containing the role_id,artist_id and album_id.
To use this intermediate table with laravel's manyToMany relationship, you can define the methods in your models specifying one attribute as pivot attribute.
For, e.g. in Artist Model:
public function Roles(){
return $this->belongsToMany('App\Roles')->withPivot('album_id');
}
public function Albums(){
return $this->belongsToMany('App\Albums')->withPivot('role_id');
}
Define similar methods for other Models also..
Update:
For getting Artist with its role in Album add following method in the Album model:
public function Artists(){
return $this->belongsToMany('App\Artist')->withPivot('role_id');
}
For roles add following method:
public function Roles(){
return $this->belongsToMany('App\Roles')->withPivot('artist_id');
}

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 relationships

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.

Using pivot table with Eloquent and Laravel

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();
}

Categories