hello I have 2 databases, namely users and profiles, profiles has a foreign key that is user_id. Then the relationship between the two is one to one.
Users migration
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Profiles migration
Schema::create('profiles', function (Blueprint $table) {
$table->id();
$table->string('alamat')->nullable();
$table->string('nip')->nullable();
$table->string('jabatan')->nullable();
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
User Model
use HasApiTokens, HasFactory, Notifiable;
protected $fillable = [
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
public function profile()
{
return $this->hasOne(Profile::class, 'user_id');
}
Profile Model
use HasFactory;
protected $table = 'profiles';
protected $guarded = [];
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
Profile Controller
public function render()
{
$userProfile = Profile::where('user_id', Auth::user()->id)->first();
if (!$userProfile) {
$profile = new Profile();
$profile->user_id = Auth::user()->id;
$profile->save();
}
$user = User::find(Auth::user()->id);
return view('profile.index', ['user' => $user]);
}
Profile index.blade.php
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Dashboard') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
Your Profile!
<div>
<p>Nama :{{ $user->name }}</p>
<p>Email : {{ $user->email }}</p>
<p>Alamat : {{ $user->profile->alamat }}</p>
</div>
</div>
</div>
</div>
</div>
the code above produces an error that is Attempt to read property "address" on null. so how do i solve it?
On your render method, you can do something like this:
if(!\Auth::check()){
abort(401);
}
$user = \Auth::user();
$user->load('profile');
return view('profile.index', ['user' => $user]);
The above code is just the optimization with eager loading. This should give you the profile address:
$user->profile->alamat
Three things you have to confirm while doing this:
Is the user authenticated? If the user is not logged in you might not get data.
Is the route wrap in auth or similar middleware? If not, you might not get auth data.
Is there data in profiles table of the current user currently logged in?
Related
I'm new to laravel and I'm learning it from laracast.
Here is my problem, I'm creating a comment form and it's php code looks like this:
<section class="col-span-8 col-start-5 mt-10 space-y-6">
<!-- Post form -->
<form method="POST" action="/post/{{ $post->slug }}/comments" class="border border-gray-200 p-6 rounded-xl">
#csrf
<header class="flex items-center">
<img src="https://i.pravatar.cc/100?id={{ auth()->id() }}" alt="" width="40" height="40" class="rounded-full">
<h2 class="ml-3 ">Want to participate?</h2>
</header>
<div class="mt-6">
<textarea class="w-full text-sm focus:outline-none focus:ring"
name="body"
cols="30" rows="10"
placeholder="Quick,think of something to say!" ></textarea>
</div>
<div>
<button type="submit" class="bg-blue-500 text-white uppercase font-semi-bold text-xs py-2 px-10 rounded-2xl hover:bg-blue-600">Post</button>
</div>
this is the corresponding route:
Route::post('post/{post:slug}/comments',[PostCommentsController::class, 'store']);
Controller:, and I suspect there could be something wrong here 'user_id'=> request()->user()->id, and I tried numerous ways for this approach like auth()->id, Auth::user()->id
<?php
namespace App\Http\Controllers;
use App\Models\Post;
class PostCommentsController extends Controller
{
public function store(Post $post){
request()->validate([
'body'=>'required'
]);
$post->comments()->create([
'user_id'=> request()->user()->id,
'body' => request('body')
]);
return back();
}
}
and this the migration table for comment
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->foreignId('post_id')->constrained()->cascadeOnDelete();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->text('body');
$table->timestamps();
migration table for post:
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->foreignId('category_id');
$table->string('slug')->unique();
$table->string('title');
$table->text('excerpt');
$table->text('body');
$table->timestamps();
$table->timestamp('published_at')->nullable();
});
If I click on post button I get the above error,tried my best to solve this problem but I couldn't. Can someone help me what's wrong with my code ?. My question may look naive as I'm new to stackoverflow community
use this code for controller
class PostCommentsController extends Controller
{
public function store(Post $post){
request()->validate([
'body'=>'required'
]);
$post->comments()->create([
'user_id'=> optional(auth()->user())->id,
'body' => request('body')
]);
return back();
}
}
user must logged in
first you must logged in
and in your route you must define your middleware if you are trying to get authenticated user's id like this
Route::post('post/{post:slug}/comments',[PostCommentsController::class, 'store'])->middleware('auth');
after that in your method/function inside controller use 'Request' class(not model class name) when you try to retrieve input from form
Laravel's 'Illuminate\Http\Request' class provides an object-oriented way to interact with the current HTTP request being handled by your application as well as retrieve the input, cookies, and files that were submitted with the request.
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request; //don't forget this
class PostCommentsController extends Controller
{
public function store(Request $request){
request()->validate([
'body'=>'required'
]);
$post->comments()->create([
'user_id'=> auth()->user()->id,
'body' => request('body')
]);
return back();
}
}
I'm creating a clone for a website where parents can create a list of things they need for their newborn baby so other people can buy it for them as a gift.
At this moment I've managed to insert data into my table and to link that row of data to the user id (so user who is logged in and completed the form).
I've managed to show all the lists from all the user id's but when I go to the dashboard of the authenticated user, I only want to show the lists who is linked to his user_id.
I can't get it working but I'm sure I have to use hasMany() and belongsTo().
This is my code:
My migration:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique;
$table->binary('password');
$table->enum('role', ['user','admin'])->default('user');
$table->timestamp('created_at');
$table->timestamp('updated_at');
});
Schema::create('lists', function (Blueprint $table)
{
$table->increments('id');
$table->foreignId('user_id')->nullable()->constrained()->onDelete('cascade');
$table->string('baby');
$table->string('vader');
$table->string('moeder');
$table->integer('telefoonnummer');
$table->string('email');
$table->string('adres');
$table->integer('huisnummer');
$table->string('toevoeging')->nullable();
$table->string('stad');
$table->integer('postcode');
$table->string('land');
});
}
My User model:
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* #var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function birthLists()
{
return $this->hasMany(Birthlist::class, 'user_id');
}
}
My Birthlist model:
class Birthlist extends Model
{
use HasFactory;
protected $table = 'lists';
protected $primaryKey = 'id';
protected $fillable =
[
'user_id',
'baby',
'vader',
'moeder',
'telefoonnummer',
'email',
'adres',
'huisnummer',
'toevoeging',
'stad',
'postcode',
'land'
];
public $timestamps = false;
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
}
My controller
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Providers\RouteServiceProvider;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use App\Models\User;
use App\Models\Birthlist;
class DashController extends Controller
{
public function dashboard($id)
{
$userId = Auth::id();
$lists = Birthlist::where('user_id')->first();
return view('dashboard', [
'lists' => $lists,
]);
}
}
My view
<body class="bg-red-100 w-screen h-screen pb">
<main class="">
<div class="text-center p-8 bg-green-100">
<p class="">welkom</p>
<h2 class="text-3xl font-bold">{{ Auth::user()->name }}</h2>
</div>
<section class="bg-red-100">
<span class="p-4"><p class="text-center text-xl font-semibold">Mijn lijsten</p></span>
#foreach ($lists->birthLists as $list)
<div class="bg-red-200 p-8 bg-gradient-to-b from-green-300 to-fuchsia-400 drop-shadow-xl text-white md:w-5/12 xl:w-3/12">
<div class="text-3xl font-bold">
{{ $list->baby }}
</div>
<div class="flex flex-row justify-between">
{{ $list->vader }} & {{ $list->moeder }}
</div>
</div>
#endforeach
</section>
</main>
#include('partials.footer')
</body>
In User model :
public function birthLists()
{
return $this->hasMany(Birthlist::class);
}
and in view :
<body class="bg-red-100 w-screen h-screen pb">
<main class="">
<div class="text-center p-8 bg-green-100">
<p class="">welkom</p>
<h2 class="text-3xl font-bold">{{ Auth::user()->name }}</h2>
</div>
<section class="bg-red-100">
<span class="p-4"><p class="text-center text-xl font-semibold">Mijn lijsten</p></span>
#foreach (auth()->user()->birthLists as $list)
<div class="bg-red-200 p-8 bg-gradient-to-b from-green-300 to-fuchsia-400 drop-shadow-xl text-white md:w-5/12 xl:w-3/12">
<div class="text-3xl font-bold">
{{ $list->baby }}
</div>
<div class="flex flex-row justify-between">
{{ $list->vader }} & {{ $list->moeder }}
</div>
</div>
#endforeach
</section>
</main>
#include('partials.footer')
</body>
and don't need to get data from controller because you can get birthLists in blade file.
I am having trouble showing user profile information in a profile page from the database which gives me Property [name] does not exist on this collection instance. (View: C:\xampp\htdocs\project_one\resources\views\profile.blade.php)
I have attached my code below
Route
Route::get('/profile', function() {
return view('profile', [
"title" => "Profile",
"profile" => Profile::all(),
"user" => User::all()
]);
});
Profile Table
public function up()
{
Schema::create('profiles', function (Blueprint $table) {
$table->id();
$table->string('name')->nullable();
$table->string('email')->unique();
$table->string('address')->nullable();
$table->string('phone')->nullable();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->timestamps();
});
}
Profile Model
class Profile extends Model
{
use HasFactory;
public function user(){
return $this->belongTo(User::class);
}
}
Function in User Model
public function profile(){
return $this->hasOne(Profile::class);
}
Blade template
<div class="form-group mb-3">
<label for="floatingName">Name</label>
<p>{{ $user->name }}</p>
</div>
your user query "user" => User::all() you are passing to the profile page is the whole users in you DB which is a collection of many users you can't get a specific user name with that......if you want the name of the currently logged in user you will have to use
<div class="form-group mb-3">
<label for="floatingName">Name</label>
<p>{{ auth()->user()->name }}</p>
</div>
without passing the user collection from your route.
or you can also pass the user logged in user through your route with this
Route::get('/profile', function() {
return view('profile', [
"title" => "Profile",
"profile" => Profile::all(),
"user" => auth()->user(),
]);
});
and in your view
<div class="form-group mb-3">
<label for="floatingName">Name</label>
<p>{{ $user->name }}</p>
</div>
Route::get('/profile', function() {
return view('profile', [
"title" => "Profile",
"profile" => Profile::all(),
"user" => User::all() // HERE IS THE PROBLEM
]);
});
User:all() returns collection of all users from the Database, For your case to get specific user on session use auth()->user()
Your Route should look like this
Route::get('/profile', function() {
return view('profile', [
"title" => "Profile",
"profile" => Profile::all(),
"user" => auth()->user(), // HERE IS THE SOLUTION
]);
});
Then you can use variable $user in a blade and get name of specific user
<div class="form-group mb-3">
<label for="floatingName">Name</label>
<p>{{ $user->name }}</p>
</div>
Look at my codes
products migration
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug')->unique();
$table->string('short_description')->nullable();
$table->text('description');
$table->decimal('regular_price');
$table->decimal('sale_price')->nullable();
$table->string('SKU');
$table->enum('stock_status', ['instock', 'outofstock']);
$table->boolean('featured')->default(false);
$table->unsignedInteger('quantity')->default(10);
$table->string('image')->nullable();
$table->text('images')->nullable();
$table->timestamps();
});
Schema::create('category_product', function (Blueprint $table) {
$table->bigInteger('category_id')->unsigned();
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
$table->bigInteger('product_id')->unsigned();
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
$table->primary(['category_id', 'product_id']);
});
}
web.php
Route::get('/product/{slug}', DetailsComponent::class)->name('product.details');
DetailsComponent.php
<?php
namespace App\Http\Livewire;
use App\Models\Product;
use Livewire\Component;
class DetailsComponent extends Component
{
public $slug;
public function mount($slug)
{
$this->slug = $slug;
}
public function render()
{
$product = Product::where('slug', $this->slug)->first();
$popular_products = Product::with('categories')->inRandomOrder()->limit(4)->get();
$related_products = Product::with('categories')
->whereHas('categories')
->where('category_id', $product->category_id)
->inRandomOrder()->limit(5)->get();
return view('livewire.details-component', compact('product', 'popular_products', 'related_products'))->layout('Home.master');
}
}
Product.php
public function categories()
{
return $this->belongsToMany(Category::class);
}
details-component.blade.php
#foreach($related_products as $related_product)
<div class="product product-style-2 equal-elem ">
<div class="product-thumnail">
<a href="{{ route('product.details', ['slug' => $popular_product->slug]) }}" title="{{ $related_product->name }}">
<figure><img src="{{ asset('assets/images/products/'.$related_product->image) }}" width="214" height="214" alt="{{ $related_product->name }}"></figure>
</a>
<div class="group-flash">
<span class="flash-item new-label">new</span>
</div>
<div class="wrap-btn">
quick view
</div>
</div>
<div class="product-info">
<span>{{ $related_product->name }}</span>
<div class="wrap-price"><span class="product-price">${{ $related_product->regular_price }}</span></div>
</div>
</div>
#endforeach
I am trying to get specific data from the database by using column category_id when a user clicks a link but I am getting this error:
I am showing categories for a product. I want to create a category manager section i have created the category manager but while i am submitting the form i am getting getting the errors as follows:
Check on this line:
public function render()
{
$product = Product::where('slug', $this->slug)->first();
$popular_products = Product::with('categories')
->inRandomOrder()
->limit(4)
->get();
$related_products = Product::with('categories')
->whereHas('categories', function ($q) use ($product) {
$q->where('category_id', $product->category_id)
})
->inRandomOrder()
->limit(5)
->get();
return view('livewire.details-component', compact('product', 'popular_products', 'related_products'))->layout('Home.master');
}
I am quite new to laravel so this might be silly mistake but I just can't figure out why it gives me this error. Right so on my website users can create posts and other users can like those posts. However, my implementation of the like system throws the following error:
ErrorException (E_ERROR)
Method Illuminate\Database\Eloquent\Collection::likes does not exist. (View: C:\xampp\htdocs\eventcw\resources\views\eventspage.blade.php)
This is my post controller method in charge of the likes:
public function postLikePost($post_id){
$loggedin_user = Auth::user()->id;
$like_user = Like::where(['user_id' => $loggedin_user, 'post_id' => $post_id])->first();
if(empty($like_user->user_id)){
$user_id = Auth::user()->id;
$post_id = $post_id;
$like = new Like;
$like->user_id = $user_id;
$like->post_id = $post_id;
$like->save();
return redirect()->route('events');
}else{
return redirect()->route('events');
}
}
My database relations seem fine,
here is my Like model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Like extends Model
{
public function user(){
return $this->belongsTo('App\User');
}
public function post(){
return $this->belongsTo('App\Post');
}
}
Here is my likes table migration:
Schema::create('likes', function (Blueprint $table) {
$table->increments('id');
$table->integer('post_id');
$table->integer('user_id');
$table->timestamps();
});
Here is my post view:
<section class="row posts">
#foreach($posts as $post)
<div class="col-md-2 col-md-offset-3">
<article class="post">
<p>{{ $post->body }}</p>
<div class="info">Posted by {{ $post->user->first_name }} {{ $post->user->last_name }} on {{ $post->created_at }}</div>
<p>This post has {{ $posts->likes()->count() }} likes </p>
Like|
</article>
</div>
#endforeach
</section>
The error indicates you are calling likes() directly on a Collection.
$posts is the collection, which you are iterating over in your blade template.
Change {{ $posts->likes()->count() }} to {{ $post->likes()->count() }}