Save data with 3 relations eloquent - mysql

I am trying to save data with eloquent relationship.
I have following three tables: User Table, Category Table and Post Table.
Post Table
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('category_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->string('heading');
$table->timestamps();
$table->foreign('category_id')->references('id')->on('categories');
$table->foreign('user_id')->references('id')->on('users');
});
Relations:
Category:
public function posts() {
return $this->hasMany('App\Post');
}
Post:
public function user() {
return $this->belongsTo('App\User');
}
public function category() {
return $this->belongsTo('App\Category');
}
User:
public function posts($category) {
return $this->hasMany('App\Post');
}
My Problem is that, how can I save post just by passing the Heading in create function. I want to use the relationship. As an example I want to use this kind of code:
$data = ['heading' => $heading];
$user->posts()->category()->create($data);
Is this possible to do this kind of stuff ?
Or any another simple way to achieve this.
EDIT
I need to create post by using this kind of relationship.
As per the process:
user will fill up the form from which I will get the data along with
the category id.
Now I need to create data for that user related with the given category id.

It's because after you call posts() method you won't get to the model's relation (only the query builder) so you will not access category() relation method. It's because posts are one-to-many relation and you don';t know exacly which record you refer to create data.
EDIT
If you want to create new post entry the the best way to sole this is:
$data = ['heading' => $heading, 'category_id' => $putHereCategoryId];
$user->posts()->create($data);
You'll need to obtain somehow the id of the desire category for the new post's entry.

Related

Laravel. Connections between tables. Get the record

I used last laravel ver. framework. I can't get access to a certain record. I have two field links to one table.
My migration:
Schema::create('application_forms', function (Blueprint $table) {
$table->unsignedBigInteger('clients_id');
$table->foreign('clients_id')->references('id')->on('clients')->onDelete('cascade');
$table->unsignedBigInteger('buyer_id')->nullable();
$table->foreign('buyer_id')->references('id')->on('clients')->onDelete('cascade');
My model
class Application_form extends Model
{
public function clients()
{
return $this->belongsTo(Client::class);
}
I used on my blade
{{$application_form->clients->FIO_Client}}
But I can't access to record with buyer_id. I get record with clients_id. How I can get access to this
$table->unsignedBigInteger('buyer_id')->nullable();
$table->foreign('buyer_id')->references('id')->on('clients')->onDelete('cascade');

how to access data of table having two foreign keys in laravel

i have a table called order_details which is having two foreign keys.
(1.) order_id
(2.) product_id
i have compacted the whole table in my view. when i access the records related to order they are working well but when i try to access the record of products which are foreign as product_id in order_detail table i am getting null.
Table of OrderDetails:
Schema::create('order_details', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('order_id');
$table->foreign('order_id')->references('id')->on('orders');
$table->unsignedBigInteger('product_id');
$table->foreign('product_id')->references('id')->on('products');
$table->integer('quantity');
$table->integer('amount');
$table->timestamps();
});
Model of OrderDetail:
public function order(){
return $this->belongsTo(Order::class);
}
public function products(){
return $this->hasMany(Product::class);
}
Model of Order:
public function orderDetails(){
return $this->hasMany(OrderDetail::class);
}
Model of Product:
public function orderDetail(){
return $this->belongsTo(OrderDetail::class);
}
i have compacted the whole table in $orderDetails on my view. when i try to access data of Order table like this:
$orderDetails[0]->Order['total_ammount']
its working fine as it is accessing the order model through order_id. but with the same way i try to get data from Product Model using product_id like this
$orderDetails[0]->Product['name']
its showing me no error but null.
Can you try be correcting these relations
OrderDetail Model
// individual row of order_details belongs to single product
public function product(){
return $this->belongsTo(Product::class);
}
Product Model to OrderDetail
I don't think this relation will be required as it hasto pass through User Model. Even though correct it as
public function orderDetails() {
return $this->hasMany(OrderDetail::class);
}

Use a column value in an other table with laravel query builder

I have two table witch named users & Inbox
In the Inbox table I have a column named sender_id that have the user_id of the sender
I want to show this message in the view. I need a query to get the sender_id from the inbox table and use that to select a certain user from the users table
I need to do this with all messages and all users.
Laravel is basicly straith foward when you use eloquent. You can always customise it.
First, almost all the time, I create a model and a migration at the same time using this : php artisan make:model Something --migration
I know you already make some models and/or migrations, but I'll go step by step to help you understand it.
So, in your case, it'll be php artisan make:model User --migration and php artisan make:model Inbox --migration. Doing this, you get two model named User and Inbox and two migration named date_create_users_table.php and date_create_inboxs_table.php. Maybe you already did the default user table with php artisan make:auth. If it's the case, don't remake one.
I'm not sure about how laravel will name the Inbox model migration... Since, I think, Laravel 5.3, the plurialisation changed and don't always just add an "S" at the end.
Then, now you got your models and migrations, let's add some line into your migration files. Since you want to do a one to many relationship. You don't need to touch the user one. Only the Inbox migration. Each Inbox is related to one User and Users can have many Inboxs. Add something like this in your migration:
public function up()
{
Schema::create('inboxs', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->foreign('user_id')->references('id')->on('users');
all other columns...
});
}
There, you can change the column's name if you need to have a sender, a recipient, etc... Do this instead :
public function up()
{
Schema::create('inboxs', function (Blueprint $table) {
$table->increments('id');
$table->integer('sender_id');
$table->foreign('sender_id')->references('id')->on('users');
$table->integer('recipient_id');
$table->foreign('recipient_id')->references('id')->on('users');
all other columns...
});
}
What we just did, it's creating the Foreign key that Laravel will use to build the query. There is one last part before the fun one. We need to create the relation in our Model. Begin with the user one:
App/User.php
public function inboxs() {
return $this->hasMany(Inbox::class);
}
And now into the App/Inbox.php model:
public function user() {
return $this->belongsTo(User::class);
}
If you need to have a Sender/Recipient/etc... go this way instead:
public function sender() {
return $this->belongsTo(User::class);
}
public function recipient() {
return $this->belongsTo(User::class);
}
Note that each of your function need to be writen in the same way it's into your migration. sender_id need a relation named sender().
Now, that our relations are done, we can simply call everything using eloquent.
$inboxs = Inbox::with('sender')->get();
This will return an array of all your Inbox into the inboxs table. You can access the sender this way: $inboxs[0]->sender();
You need the id, do this: $sender_id = $inboxs[0]->sender_id;
The sender name : $sender_name = $inboxs[0]->sender->name;
If you want to get one Inbox and you have the id, just do this $inbox = Inbox::with('sender')->find($id);
This way you don't get an array, only one result and can access the sender directly using $sender_name = $inbox->sender->name; instead of having to add [0] or using a foreach loop.
You can get all messages sended by a user using something like this:
$inboxs = Inbox::where('sender_id', $sender_id)->get();
Finally, you can pass your data to the view using:
return view('path.to.view')->with('inbox',$inbox);
Into the view you do this to show the sender's name:
//If view.blade.php
{{$inbox['sender']['name']}} //work a 100%
{{$inbox->sender->name}} //I'm not sure about this one
//If not using blade
<?php echo $inbox['sender']['name']; ?>
There is a lot of thing you can do using Eloquent and you can add as much condition you want. The only thing I suggest you to really do if you want to use Eloquent, be aware about the n+1 problem. There is a link where I explain it. Look for the EDIT section of my answer.
If you need some documentation:
Laravel 5.3 Relationships
Laravel 5.3 Migrations
Laravel 5.3 Eloquent
I think you should update your code like:
$user_messages = DB::table('messages')
->select('messages.id as msgId','messages.message as message','users.id as userId','users.user_name as user_name')
->join('messages','messages.user_id','=','users.id')
->where('messages.user_id',$user_id)
->get();
return view("view.path")
->with('messages',$user_messages);
Hope this work for you!
In Model :
namespace App;
use Illuminate\Database\Eloquent\Model;
class Messages extends Model
{
protected $table = 'table_name';
public function sender()
{
return $this->belongsTo('App\User', 'sender_id', 'id');
}
}
In Controller :
public function functionName($user_id){
$messages = Messages::where('sender_id', $user_id)->get();
return view("view.path")
->with('messages',$messages);
}
In view, you can access seder details like this $message->sender->name for name for id $message->sender->id

Relationships between tables in laravel using backpack package

I am using backpack CRUD package to create my website project in laravel 5.2
I want to establish a relationship between two tables. First table is called customer and second table is called transaction. Each customer has many transaction(1:N relationship).
Customer table record:
ID Name
123456 xyz
Transaction table record:
ID CustomerID
101010 123456
I know that I have to specify the relation in the customer model. But, how can I display the result of the relationship in CRUD ?
You should have relationships on both the Transaction and the Customer models, so you can do $customer->transactions and $transaction->customer:
class Customer extends Model
{
/**
* Get the comments for the blog post.
*/
public function transactions()
{
return $this->hasMany('App\Transactions', 'CustomerID', 'ID');
}
}
and
class Transaction extends Model
{
/**
* Get the comments for the blog post.
*/
public function customer()
{
return $this->belongsTo('App\Customer', 'CustomerID', 'ID');
}
}
Spend some time in the Eloquent Relationships Documentation. It's really important to understand them if you want to be a Laravel developer.
In order to display the relationship in the CRUD, you can then use Backpack's select column type to display it in the table view and select or select2 field types to display it in the add/edit views. Read the CRUD Example Entity to better understand how that works.
First of all when you are creating migrations for both tables, table which contain Foreign Key (FK) must have field like this:
public function up(){
$table->increments('id');
$table->integer('customerID')->unsigned();
}
After that you are need to call next command into console
php artisan migrate
Next is going next commands:
php arisan backpack:crud customers
php arisan backpack:crud transactions
After that you need to define functions in models which returns values from other tables. Customer models need to have next function
public function transactions(){
return $this->hasMany('Transaction');
}
Transaction model must have next function
public function customer() {
return $this->belongsTo('Customer');
}
Next you must add CRUD field in Customer controller to display
transactions in select box.
$this->crud->addField([
'label' => 'Transactions', // Label for HTML form field
'type' => 'select2', // HTML element which displaying transactions
'name' => 'customerID', // Table column which is FK for Customer table
'entity'=> 'customer', // Function (method) in Customer model which return transactions
'attribute' => 'ID', // Column which user see in select box
'model' => 'Transaction' // Model which contain FK
]);
Hope this helps :)
After you built onetomany relationship with transaction, you can get the results.
$customer=Customer::where(['id'=>'123456'])->with('transaction')
->first();
print_r($customer->Name); // gives the customer name
foreach($customer->transaction as $cid)
{
print_r($cid->CustomerID); // gives the customer id
}
Laravel Relationships Documentation is always helpful. Go through it.

Include specific column from related-models table

Using Laravel 5.1: Given two related models, User and Item, with through table Item_User, how can I include a specific column from the through table, item_count using a with statement?
Item_User table:
Query:
$userGameProfile = User::with([
'items' => function($query) use ($profile_id) {
$query->with(['phrases'])->where('profile_id', '=', $profile_id);
}])->find($id);
Adding ->select('item_count') to this query only returns item count, and not the related item objects. Adding ->select('*') gets me the items and fields I want, but breaks the nested with(['phrases']) relationship I need to get related phrases to items.
I was told I should use withPivot, but I cannot find documentation or examples on how to use this.
Preferably, I'd like to add this to the relationship, rather than each query.
Models:
User:
public function items()
{
return $this->belongsToMany(Item::class, 'user_item');
}
Item:
public function users()
{
return $this->belongsToMany(User::class, 'user_item');
}
public function phrases()
{
return $this->belongsToMany(Phrase::class, 'item_phrase');
}
Phrase:
public function items()
{
return $this->belongsToMany(Item::class, 'item_phrase');
}
This article highlights how to include additional information from the pivot table.
In User model, I know I will always want to include item_count from user_items pivot table, so you can add withPivot to the relation to items:
public function items()
{
return $this->belongsToMany(Item::class, 'user_item')
->withPivot('item_count');
}
User now comes back with items and pivot data: