Append new element to eloquent collection - php

I have two tables posts and photos. Each post has 5 photos. I want to list in view each post with one photo (profile pic), first picture.
$published_post = Post::where('created_by',auth()->user()->id)
->where('status','published')
->get();
$photo = Photo::where('post',$published_post->id)->get();
These two gives me two different collection. How can I add the first photo of a particular post to its array so in view I can display using a foreach loop.
This is how I want in view:
#foreach($published_post as $item)
{{ $item->title }}
{{ $item->profile_photo }}
#endforeach
I tried put and push, but doesn't seem to be working. Not sure how exactly does we append a new key value pair to an object.
My two models:
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title');
$table->timestamps();
});
Schema::create('photos', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('image');
$table->integer('post');
$table->timestamps();
});
class Post extends Model
{
protected $table = 'posts';
}
class Photo extends Model
{
protected $table = 'photos';
protected $fillable = ['image', 'post'];
}

Post Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
/*This is used to specify the table which this model is associated with*/
protected $table = 'posts';
protected $fillable = [
'title'
];
public $timestamps = true;
public function photos(){
return $this->hasMany(Photos::class,'post');
//post is the foreign key for posts table
}
}
Photo Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Photo extends Model
{
/*This is used to specify the table which this model is associated with*/
protected $table = 'photos';
protected $fillable = [
'image', 'post'
];
public $timestamps = true;
}
View:
#foreach($published_post as $item)
{{ $item->title }}
{{ $item->photos->first()->image }} // photos relation is invoked and fetched first image
#endforeach

You need to create 2 Models, one for Posts and one for Photos.
php artisan make:model Post
php artisan make:model Photo
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Posts extends Model
{
//
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Photo extends Model
{
//
}
Then create a hasMany relationship on the Post model to link to the Photo model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Photo;
class Post extends Model
{
public function photos()
{
return $this->hasMany(Photo::class);
}
}
Then in your view you can lazy load the photos whenever you like
#foreach($posts as $post)
{{ $post->title }}
{{ $post->photo[0]->name}}
#endforeach
The syntax to go in your view will be slightly different, but this gives you a good idea on how the functionality should work.

Ok, first you should change your Post model like this:
class Post extends Model
{
protected $table = 'posts';
public function photos()
{
return $this->hasMany(Photo::class, 'post');
}
}
And then, add the following to your Photo model:
class Photo extends Model
{
protected $table = 'photos';
public function post()
{
return $this->belongsTo(Post::class, 'post');
}
}
With this, you've created the relation between your models, and now you can get your data this way:
$published_post = Post::where('created_by',auth()->user()->id)
->where('status','published')
->with('photos')
->get();
And in your view, you can get the first photo this way:
#foreach($published_post as $item)
{{ $item->title }}
{{ $item->photos()->first()->name }}
#endforeach
For more info on relations, you might want to read the docs.
I hope this helps!

Related

Laravel hasOne() Function Using $this when not in object context

I have 2 models named AdminContent, AdminCategory. I have content_category_id in my admin_contents table. I have category_id and category_name in my admin_categories table. I linked category_id with content_category_id foreign.
I am using the hasOne() function in my Admin Content model. But I get the error Using $this when not in object context!
My main goal is to get content_category_id value from admin_categories table name column
Migrations
// Admin Categories Migration
Schema::create( 'admin_categories', function(Blueprint $table) {
$table->bigIncrements('ctgry_id')->unique();
$table->string('category_name', 50)->unique();
$table->timestamps();
});
// Admin Contents Migration
Schema::create('admin_contents', function (Blueprint $table) {
$table->bigIncrements('cntnt_id')->unique();
$table->string('content_title');
$table->text('content_content');
$table->string('content_slug');
$table->bigInteger('content_category_id');
$table->foreign('content_category_id')->references('ctgry_id')->on('admin_categories');
$table->string('content_status');
$table->string('create_user');
$table->string('content_tags');
$table->string('content_excerpt');
$table->dateTime('posted_at');
$table->timestamps();
});
Models
// AdminContent Model
protected $table = "admin_contents";
protected $fillable = [
'content_title', 'content_content',
'content_category_id', 'content_status', 'create_user','content_tags',
'content_excerpt',
'created_at', 'updated_at'
];
protected $guards = [
'cntnt_id',
];
public function setCategoryName()
{
return $this->hasOne(AdminCategory::class);
}
When I want to access with $this->hasOne(AdminCategory::class) I get this error!
First: relationships in Laravel are based in standardize models, using 'id' as column name for ids. If you are using another name for firstKey, you should add it to relationship definition, as stated in documentation. I mean, your relationship should not work because Eloquent doesn't know which are your tables first keys.
Second: when you define a relationship you should call id from your model. So how are you accessing to $this->hasOne(AdminCategory::class)?
It should be something like AdminContent::with('setCategoryName')
Maybe showing some code from your controller we can give you a more accurate reply.
What I want is this,
I get the blog content with query and print it. But I am printing the content_category_id value as the id value in category table. What I need to do is get the content_category_id and the id value in the category table, the category name linked to that id. Thanks in advance for your help.
Admin Content Model
namespace App\Models\Admin;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class AdminContent extends Model
{
use HasFactory;
protected $table = "admin_contents";
protected $primaryKey = 'cntnt_id';
protected $fillable = [
'content_title', 'content_content',
'content_category_id', 'content_status', 'create_user','content_tags',
'content_excerpt',
'created_at', 'updated_at'
];
protected $guards = [
'cntnt_id',
];
public function _all()
{
return self::all();
}
public static function setCategoryName()
{
return $this->hasOne(AdminCategory::class, 'content_category_id', 'ctgry_id');
}
}
Admin Category Model
namespace App\Models\Admin;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class AdminCategory extends Model
{
use HasFactory;
protected $table = 'admin_categories';
protected $primaryKey = 'ctgry_id';
protected $fillable = [
'category_name', 'updated_at'
];
protected $quards = [
'ctgry_id', 'created_at'
];
}
Post Controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Admin\AdminContent;
class PostController extends Controller
{
public function index()
{
return view('frontend.blog');
}
public function getCategoryName()
{
return AdminContent::find(1)->setCategoryName;
}
}
MySQL Tables
https://www.hizliresim.com/2z0337a

Laravel Model relationship "Page have many Attachments"

I have models:
Page:
id
slug
Image
id
file
Video
id
file
I need the Page model to have a relation with several Image and Video models through one relationship, like
foreach($page->attachments as $attachment)
{
// $attachment can be Image or Video
}
And inserts like
$attachments = [$image, $video];
$page->attachments()->saveMany($attachments);
I tried to make a morph relationship, but nothing comes of it, please help.
Create an Attachment Model and attachments Table with the following columns/properties:
id
file
page_id
type (video/image)
then you could add hasmany relationship to your page model
public function attachments()
{
return $this->hasMany(Attachment::class);
}
Then you can fetch the attachment like you tried
In order to achieve this you have to make table for relations. This table should be defined like this:
page_image_video
id
page_id
image_id
video_id
And fields page_id, image_id and video_id should be a foreign keys. This is a table where you will save you attachments for your page. After that, you can define method attachments() in you Page Model with hasMany().
Create Migration :
Page Table :
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string("slug");
$table->timestamps();
});
Image Table :
Schema::create('tags', function (Blueprint $table) {
$table->increments('id');
$table->string("file");
$table->timestamps();
});
Videos Table :
Schema::create('video', function (Blueprint $table) {
$table->increments('id');
$table->string("file");
$table->timestamps();
});
Pageables Table :
Schema::create('pageables', function (Blueprint $table) {
$table->integer("pages_id");
$table->integer("pageable_id");
$table->string("pageable_type");
});
Create Model :
Now, we will create Pages, Images and Video model. we will also use morphToMany() and morphedByMany() for relationship of both model.
Video Model :
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Video extends Model
{
use HasFactory;
protected $table='video';
protected $primaryKey='id';
protected $guarded = [];
public function pages()
{
return $this->morphToMany(Pages::class, 'pageable');
}
}
Images Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Images extends Model
{
use HasFactory;
protected $table='image';
protected $primaryKey='id';
protected $guarded = [];
public $timestamps = false;
public function pages()
{
return $this->morphToMany(Pages::class, 'pageable');
}
}
Pages Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Relation;
class Pages extends Model
{
use HasFactory;
protected $table='page';
protected $primaryKey='id';
protected $guarded = [];
public $timestamps = false;
public function posts()
{
return $this->morphedByMany(Images::class, 'pageable');
}
/**
* Get all of the videos that are assigned this tag.
*/
public function videos()
{
return $this->morphedByMany(Video::class, 'pageable');
}
}
Retrieve Records :
$pages = Pages::find(1);
foreach ($pages->posts as $post) {
var_dump($post);
}
foreach ($pages->videos as $video) {
print_r('<br>');
//var_dump($video);
}
Create Records :
$page = Pages::find(1);
$img = new Images();
$img->file = "test insert";
$page->posts()->save($img);
All done.

belongsTo relationship in laravel 5.8

I want to make a relation between post and user to be able to get all posts by this way $user->posts() and to get user by this way $post->user()
I made belongsTo function but i need a way so when i get the user i can find all his posts somehow
also when i get the post i used \App\Post::find(1)->user()->name it return nothing
Post Model
class Post extends Model
{
public function user() {
return $this->belongsTo('App\User',null,'userid');
}
}
Post DB Structure
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title');
$table->longText('body');
$table->string('thumbnail');
$table->integer('views');
$table->integer('likes');
$table->bigInteger('userid');
$table->integer('categoryid');
$table->timestamps();
});
User Model has nothing in it rather than laravel defaults because user has no columns that refer to posts
User DB Structure is Laravel Default
Foreach code:
#foreach(\App\Post::find(4)->user() as $user)
<p>{{$user->name}}</p>
#endforeach
i expected it to get the user name but it didn't..
Use the hasMany relationship.
Within user model:
public function posts()
{
return $this->hasMany(Post::class, 'userid', 'id');
}
Now, you are able to get all user posts:
$posts = User::find($someId)->posts()->get();
//or
$posts = User::find($someId)->posts;
Docs about has many relationship
Hope it helps.
In User model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\User;
class Post extends Model
{
/**
* Get the comments for the blog post.
*/
public function user()
{
return $this->belongsTo('App\User');
}
}
In User model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Post;
class User extends Model
{
/**
* Get the posts for the user.
*/
public function comments()
{
return $this->hasMany('App\Post');
}
}
Now you can access posts of user as App\User::find(id)->posts

Laravel : One is to Many Relationship, get foreign key value

I'm currently working on productcategories and products relationship
which is one is to many.
I wonder why i'm having this error
Call to undefined method stdClass::products()
Here's my model for Products
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
public $table = "products";
public $fillable = ['productcategory_id',
'name',
'description',
'price',
'pic',
'availability',
'featured',
];
public function productcategory()
{
return $this->belongsTo('App\ProductCategory');
}
}
and here's my model for Product Category
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ProductCategory extends Model
{
public $table = "productcategories";
public $fillable = ['name',
'description',];
public function products(){
return $this->hasMany('App\Product','productcategory_id','id');
}
}
and Here's my view file
#foreach($productcategories as $productcategory)
#foreach($productcategory->products() as $product)
{{ $product->name }}
#endforeach
#endforeach
Please help me i'm getting this error all the time.
Just shooting in the dark here, but I would first remove the parentheses in your view file from $productcategory->products(). If that doesn't solve the issue, dd($productcategories) in your Controller and verify that you're passing a Collection of ProductCategory as I wouldn't expect the resulting error to include reference to "stdClass".

laravel where on relationship table

I am using laravel, I have a main table with 'projects' and a table with 'users', an intermediate table linking the two as a many-to-many relationship.
Now I want to display a list of projects, but if they are over 'projects.max_people' then they should be hidden from this list, how do I do this in laravel?
The problem is im 'get()'ing the users in the view, after I did Project::get()... how do I add this where condition?
You should create a new object called ProjectUser or so. In this object should contain a 'project_id' and 'user_id'.
Then, your Project model would look something like this:
<?php
class Project extends \Eloquent
{
protected $table = 'projects';
public function projectUsers(){
$this->hasMany('ProjectUser', 'project_id');
}
}
The User class:
<?php
class Project extends \Eloquent
{
protected $table = 'projects';
public function projectUsers(){
$this->hasMany('ProjectUser', 'user_id');
}
}
The ProjectUser class:
class ProjectUser extends \Eloquent
{
protected $table = 'project_users';
public function project(){
$this->belongsTo('Project'`enter code here`, 'project_id');
}
public function user(){
$this->belongsTo('User', 'user_id');
}
}
Now, you can get the users of a project like so:
$projects = Project::with('projectUsers.user')->get();
When looping through these objects you can access the user like this:
#foreach($projects as $project)
#foreach($project->projectUsers as $projectUser)
{{ $projectUser->user->id }}
#endforeach
#endforeach

Categories