I getting started with Eloquent, and I've ran into a problem. I trying to setup a many to many relation schema + model.
Here is the code:
routes.php snippet:
$user1 = User::findOrFail(1);
$user2 = User::where('username', '=', 'TestUser')->get();
// we make $user1 to follow $user2
$user1->followedBy()->save($user2);
User model snippet:
public function followedBy() {
return $this->belongsToMany('User', 'user_follows', 'user_id', 'follow_id');
}
public function following() {
return $this->belongsToMany('User', 'user_follows', 'follow_id', 'user_id' );
}
DB Schema snippet:
Schema::create('user_follows', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id');
$table->integer('follow_id');
$table->timestamps();
});
The error I get when I visit the routes:
Argument 1 passed to Illuminate\Database\Eloquent\Relations\BelongsToMany::save() must be an instance of Illuminate\Database\Eloquent\Model, instance of Illuminate\Database\Eloquent\Collection given, called in /Applications/MAMP/htdocs/Laravel/proj2/app/routes.php on line 84 and defined
The error says it all:
$user2 = User::where('username', '=', 'TestUser')->get();
// returns Collection
You need this instead:
$user2 = User::where('username', '=', 'TestUser')->first();
// returns single Model
And by the way:
// we make $user1 to follow $user2
$user1->followedBy()->save($user2);
it's $user2 to follow $user1 and use this:
$user1->followedBy()->attach($user2);
For save is saving the $user2 model first, what is redundant here. It's used in such cases:
$user2 = new User;
// assign some properties
...
$user1->followedBy()->save($user2);
Related
I have many to many relation which is inserting data correctly but when I try to fetch data it gives me no data.
one table is boss and other is workers
Migration
<?php
public function up()
{
Schema::create('boss_worker', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('worker_id');
$table->unsignedBigInteger('boss_id');
$table->timestamps();
});
}
Boss model relation
public function workers()
{
return $this->belongsToMany(\App\Models\Admin\Worker::class,'boss_worker');
}
How I am trying to fetch data
public function index()
{
$boss = Boss::find(1);
dd($boss->workers);
}
How I am inserting data
$input = $request->all();
$workers = $input['workers'];
$input['workers'] = implode(',', $workers);
$boss = Boss::where('staff_id',$request->boss)->first();
$worker_gangs = $boss->workers()->sync($workers);
It is not fetching any data
use
public function index()
{
$boss = Boss::with('workers')->find(1);
}
When you call a relationship from a model you are calling to Illuminate\Database\Eloquent\Builder so, you can access and apply any filter or query with the Query Builder, to fetch the data from that relationship, you have to use these methods to execute the query
->get();
->first();
your code have to be:
$boss = Boss::find(1);
$workers = $boss->workers()->get();
dd($workers);
or you can make eager loading with the Boss model
$boss = Boss::with('workers')->find(1);
dd($boss->workers);
There are two users in my users table user1 and user2
the user2 wants to rate user1
i have created a Rating table
which is as
Schema::create('ratings', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('user_id');
$table->string('rating')->nullable();
$table->string('review')->nullable();
$table->integer('rated_user_id');
$table->timestamps();
});
i have also created a model named Rating and defined a realtionship to the user
such as
public function user()
{
return$this->hasMany(User::class);
}
the code in my user model is as follow
public function Rating()
{
return $this->hasOne(Rating::class);
}
the code inside Ratingcontroller store function is as follow
public function store(Request $request)
{
//
$rating = new Rating;
$rating->fill($request->all());
$rating->user_id = Auth::id();
$rating->save();
return redirect()->back();
}
the problem is that in the rating table
every things looks fine
user_id is getting the id who is trying to post comment
and rated_user_id is givving the id to which the user is giving rating too
but the user is only able to rate himself not other users ..
The image in db is correct and Your store method in RatingsController is also works as expected.
So You want from us to give You code example to ProfileController method to get ratings provided by user and provided to user.
1) You've to add to User model following relation:
public function ratingsProvidedByMe()
{
return $this->hasMany(Rating::class, 'user_id', 'id');
}
public function ratingsProvidedToMe()
{
return $this->hasMany(Rating::class, 'rated_user_id', 'id')
}
2) in Rating model:
public function ratedBy()
{
return $this->belongsTo(User::class, 'user_id');
}
public function ratedTo()
{
return $this->belongsTo(User::class, 'rated_user_id');
}
3) in Your ProfileController:
public function view(Request $request)
{
$ratingsProvidedByMe =
Rating::with('ratedTo')
->where('user_id', Auth::id())
->all();
$ratingsProvidedToMe =
Rating::with('ratedBy')
->where('rated_user_id', Auth::id())
->all();
$me = $user = Auth::user();
return view(
'profiles.view',
compact(
'ratingsProvidedByMe',
'ratingsProvidedToMe',
'user', 'me'
)
);
}
P.S. it's just an example, adapt my example to Your project Yourself.
I want to get weekly reports and monthly reports on my application, but I don't know where to start.
I use Laravel 5.7, I have tried a number of experiments that I have searched for on the internet, but they don't work.
My table
Schema::create('surat_keluars', function (Blueprint $table) {
$table->increments('id');
$table->string('nomor_surat')->unique();
$table->integer('instansi_id')->unsigned();
$table->string('perihal');
$table->date('tanggal_surat');
$table->date('tanggal_kirim');
$table->string('lampiran');
$table->timestamps();
$table->foreign('instansi_id')->references('id')->on('instansis');
});
My model
class SuratKeluar extends Model
{
protected $fillable = [
'nomor_surat', 'instansi_id', 'perihal', 'tanggal_surat', 'tanggal_kirim', 'lampiran'
];
public function instansi()
{
return $this->belongsTo('App\Instansi');
}
}
And and I have tried using this controller, but I don't know how to display it in view blade
public function day()
{
$data= SuratKeluar::select('id', 'nomor_surat', 'created_at')
->get()
->groupBy(function($val) {
return Carbon::parse($val->created_at)->format('m');
});
}
I hope someone can help me.
based on your question if you want to show it in view you can return the controller to the view like this:
public function day(){
$data= SuratKeluar::select('id', 'nomor_surat', 'created_at')
->get()
->groupBy(function($val) {
return Carbon::parse($val->created_at)->format('m')});;
return view('name_of_the_view')->with('name_of_variable_in_view', $data);
}
please make sure the $data variable is the data for your report by using var_dump like this
public function day(){
$data= SuratKeluar::select('id', 'nomor_surat', 'created_at')
->get()
->groupBy(function($val) {
return Carbon::parse($val->created_at)->format('m')});;
var_dump($data);
}
and please ensure that you already build the view for your review you can read the documentation in here https://laravel.com/docs/5.7/views
I've got a query to get messages:
public function getMessagesFor($id)
{
$messages = Message::where(function($q) use ($id) {
$q->where('from', auth()->id());
$q->where('to', $id);
})->orWhere(function($q) use ($id) {
$q->where('from', $id);
$q->where('to', auth()->id());
})->get();
}
and this logic works as it should, no errors all is ok. Now I want to get messages directly via model relatioship with other user (not authenticated one)
so in User model I wrote:
public function messages()
{
return $this->hasMany(Message::class, 'to', 'id')
->where('messages.from', auth()->id());
}
And this basically gives the same result as first where clause in getMessages function. This relatioship works ok.
The problem is that I don't know how to code the second part of where clause. I don't have access to $id in my model so how should I approach to this? Any ideas how to code it?
edit: message migration:
Schema::create('messages', function (Blueprint $table) {
$table->increments('id');
$table->integer('from')->unsigned();
$table->integer('to')->unsigned();
$table->boolean('read')->default(false);
$table->integer('offer_id')->nullable();
$table->mediumText('body')->nullable();
$table->timestamps();
});
So I think the problem is the model relationship (user) is already set to get message where the user is the message reciever(to),
$this->hasMany(Message::class, 'to', 'id')
so you need to define another relationship to get messages where the user is the sender (from), so you have this
//user is reciever
public function sentMessages() {
return $this->hasMany(Message::class, 'to', 'id')
->where('messages.from', auth()->id()); }
//user is sender
public function recievedMessages() {
return $this->hasMany(Message::class, 'from', 'id')
->where('messages.to', auth()->id()); }
Anyway I advise you go with your first approach.
Okay, so adding your final soultion to get messages
//get all messages with
$this->sentMessages->merge($this->recievedMessages)
Let's say I have User Model. Each User has Pet model.
both have relationship setup correctly.
When I get the user data along with his pets, I do this:
return $this->with('pets');
but what if I want to return the pet name only with the user data?
I've been trying that:
return $this->with('pets.name');
Didn't work for me.
Model
Class User extends Model ()
{
...
public function pets()
{
return $this->hasOne('App\Model\Pet');
}
}
Controller or Repository or any other object
function getUserDetails (Request $request)
{
$userId = $request->get('id');
$findUserById = User::find($userId);
$fullName = $findUserById->pets->fullname;
}
You can do this way :
$users_with_pet_name = DB::table('users')
->join('pets', 'users.id', '=', 'pets.user_id')
->select('users.*', 'pets.name')
->get();
Check out joins section: https://laravel.com/docs/5.1/queries#joins