I work on one project with Laravel 5.2 and Entrust package for ACL.
In this project I need for one Role ('venue_owner') in which venue is owner. I have also table called venue and I have no idea how to make this relations, because table users is general for all type of users.
How to make this relations to know what user from role venue_owner is owner of what venues ?
Have you created your Migrations yet by running: php artisan enthrust:migration? if not it, run it and then inside the file that is generated, add your own tables like below within the up() Method of the Enthrust Migration File:
<?php
public function up() {
// SOME OTHER TABLE CREATION CODES...
Schema::create('venue_owner', function (Blueprint $table) {
$table->increments('id');
$table->integer("user_id")->unsigned();
$table->timestamps();
// CREATE THE ASSOCIATION/RELATIONSHIP USING FOREIGN KEY
$table->foreign('id')
->references('id')
->on('venue')
->onDelete('cascade');
});
Schema::create('venues', function (Blueprint $table) {
$table->increments('id');
$table->integer("venue_owner_id")->unsigned();
$table->string("venue");
$table->timestamps();
// CREATE THE ASSOCIATION/RELATIONSHIP USING FOREIGN KEY
$table->foreign('venue_owner_id')
->references('id')
->on('venue_owner');
});
}
public function down() {
// OTHER DROP COMMAND CODES...
Schema::drop('venue_owner');
Schema::drop('venues');
}
Then in your Eloquent Model Class you can explicitly set the $this->hasMany() like so:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class VenueOwner extends Model {
/**
* GET ALL THE venues FOR THE venue_owner .
*/
public function venues() {
return $this->hasMany('App\Venues');
}
/**
* GET ALL THE user FOR THE venue_owner .
*/
public function user() {
return $this->hasOne('App\User');
}
And in your Venues Eloquent Model Class, you do something like:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Venues extends Model {
/**
* GET THE venue_owner FOR venue(s).
*/
public function venueOwner() {
return $this->belongsTo('App\VenueOwner');
}
Last but not least in your Users Eloquent Model Class, you do something like:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Users extends Model {
/**
* GET THE user Information FOR venue_owner.
*/
public function venueOwner() {
return $this-> hasOne('App\VenueOwner');
}
Now, you can get all information about the venue_owner and his venues and roles & permissions using the user_id.
Related
All polymorh examples I found are one to many if I get it correct. (Tag to Post / Video e.g)
In my Case the parent class is multiple and the child class also. Therefore i set up the pivot table
Tables
Person
id
Venture
id
Capital
id
Estate
id
PIVOT TABLE
Revenues
emitter_id //ID of the revenue emitting class (Venture, Capital, Estate)
emitter_type // Class of the Emitter (App\Models\Venture App\Models\Estate)
receiver_id // Id of Receiver (Venture or Person)
receiver_type // type of Receiver (App\Models\Venture or App\Models\Person)
revenue
In the Estate Model i try this
public function revenuePersons()
{
// searched type, own type/id ,tabel own ID to search id
return $this->morphToMany(Person::class, 'emitter' ,'revenues' ,'emitter_id','receiver_id')
->withPivot('revenue');
}
One the Person Model
public function estaterevenues(){
// searched type, own type/id ,tabel own ID to search id
return $this->morphToMany(Estate::class, 'receiver' ,'revenues' ,'receiver_id','emitter_id')
->withPivot('revenue');
}
The Code works but in some cases i get additional relations back. So it seams the searched _type is not correctly considered.
So i started to implement a own database query function that gives me the Revenue Entry back. It works correctly.
Revenue Model
public function getRevenue($ownside, $emitter_id = Null, $emitter_type,$receiver_id=Null, $receiver_type ){
$revenue = DB::table('revenues')
->where('emitter_id', $emitter_id)
.....()->get()}
But I am not able to do something like
$persons->getRevenues
because a Relationship is expected as return value
So if anyone has an idea how to do that correctly I would be very happy. Or some other best practices for this many to many approach.
The second Question is how to get all revenue receiver at once.
Instead of
$estate->revenuepersons
$estate->revenueventures
Have something like
$estate->revenues //that list both, Ventures and Persons
And here a Class Diagram
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
/**
* Get all of the tags for the post.
*/
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
class Video extends Model
{
/**
* Get all of the tags for the post.
*/
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
/**
* Get all of the posts that are assigned this tag.
*/
public function posts()
{
return $this->morphedByMany(Post::class, 'taggable');
}
/**
* Get all of the videos that are assigned this tag.
*/
public function videos()
{
return $this->morphedByMany(Video::class, 'taggable');
}
}
$post = Post::find(1);
dd($post->tags);
$video = Video::find(1);
dd($video->tags);
$tag = Tag::find(1);
dd($tag->posts);
$tag = Tag::find(1);
dd($tag->videos);
posts table migration:
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string("name");
$table->timestamps();
});
videos table migration:
Schema::create('videos', function (Blueprint $table) {
$table->increments('id');
$table->string("name");
$table->timestamps();
});
tags table migration:
Schema::create('tags', function (Blueprint $table) {
$table->increments('id');
$table->string("name");
$table->timestamps();
});
taggables table migration:
Schema::create('taggables', function (Blueprint $table) {
$table->integer("tag_id");
$table->integer("taggable_id");
$table->string("taggable_type");
});
I have an application where an Invoice can belong to the client or supplier. Now I used the morph things in my current scenario. I want to create the proper anchor by using the morph relation But I didn't find the best way with Laravel
Client.php
class Client extends Model
{
/**
* Get the client's invoices.
*/
public function invoices()
{
return $this->morphMany('App\Invoice', 'contact');
}
}
Supplier.php
class Supplier extends Model
{
/**
* Get the supplier's invoices.
*/
public function invoices()
{
return $this->morphMany('App\Invoice', 'contact');
}
}
Invoice.php
class Invoice extends Model
{
/**
* Get the owning contact model.
*/
public function contact()
{
return $this->morphTo();
}
}
Now at somewhere(invoice details page), where I want to add the anchor to the contact of the invoice(either supplier or client) But I need to know if there is any Laravel's way.
If the contact of the invoice belongs to App\Client then the href will be "/clients/contact_id" or if it belongs to App\Supplier then it should be "/supplier/contact_id"
invoices/show.blade.php
<b>{{ $invoice->contact->name }}</b>
You can try given solution for you problem.
<?php
//You can see here for all table migration files
// For Client Table
Schema::create('client', function (Blueprint $table) {
$table->increments('id');
$table->string("client_name");
$table->timestamps();
// You can add your more fields and you can change field name also
});
// For Supplier Table
Schema::create('supplier', function (Blueprint $table) {
$table->increments('id');
$table->string("supplier_name");
$table->timestamps();
// You can add your more fields and you can change field name also
});
// For Invoice Table
Schema::create('invoices', function (Blueprint $table) {
$table->increments('id');
$table->morphs('invoice');
$table->timestamps();
// You can add your more fields and you can change field name also
});
//Note:
$table→morphs('invoice') would automatically create two columns using the text passed to it + “able”. So it will result in invoiceable_id and invoiceable_type.
?>
Here are your model for morphTo replationship
Client Model: Client.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Client extends Model
{
/**
* Get all of the Client's invoices.
*/
public function invoices()
{
return $this->morphMany(Invoices::class, 'invoiceable');
}
}
?>
Supplier Model: Supplier.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Supplier extends Model
{
/**
* Get all of the Supplier's invoices.
*/
public function invoices()
{
return $this->morphMany(Invoices::class, 'invoiceable');
}
}
?>
Invoices Model: Invoices.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Invoices extends Model
{
/**
* Get all of the owning invoiceable models.
*/
public function invoiceable()
{
return $this->morphTo();
}
}
?>
Now you can retrieve records using Client and Supplier using polymorphic relationship.
Retrieve records using client models.
$client = Client::find(1);
dd($client->invoices);
Retrieve records using Supplier models.
$supplier = Supplier::find(1);
dd($supplier->invoices);
You can also retrieve records
$client = Client::find(1);
foreach ($client->invoices as $invoice) {
<a href="{{ route('view-client', ['id' => $invoice->id]) }}">
<b>{{ $invoice->client_name }}</b>
</a>
}
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
I have specified the table name in the model class.
Laravel 5.6, PHP 7
namespace App;
use Illuminate\Database\Eloquent\Model;
class SizeProduct extends Model
{
protected $table = 'size_product';
protected $fillable = ['product_id', 'size_id'];
}
This is my migration:
class CreateSizeProductTable extends Migration
{
public function up()
{
Schema::create('size_product', function (Blueprint $table) {
//some code here
});
}
public function down()
{
Schema::dropIfExists('size_product');
}
But i still get this error:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'db_name.product_size' doesn't exist
maybe sizeproduct is your pivot table for manytomany relation, so as described here, The pivot table is derived from the alphabetical order of the related model names (so in your case product comes first).
You can change it in relation defining code:
public function products()
{
return $this->belongsToMany(Size::class,'size_product');
}
Or you may prefer to create separate migration for your pivot table.
I am setting up a one to one relationship in a laravel application, but I am getting the error "trying to get property of non-object" when I try to reference a related table.
My Contractor.php model:
class Contractor extends Eloquent {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'contractor';
function profile() {
return $this->hasOne('ContractorProfile');
}
}
My ContractorProfile.php model:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class ContractorProfile extends Eloquent {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'contractor_profile';
public function contractor() {
return $this->belongsTo('Contractor');
}
}
here is the snippet of my view file
show.blade.php
<div>
<h4>{{ $contractor->profile->tag_line }}</h4></p>
</div>
If I just call $contractor->profile the page loads but nothing is echoed back. If I add the ->tag_line, I get the "trying to get property of non-object" error. tag_line is a column name inside of my contractor_profile table.
Do you see an error that I am making?
TIA
EDIT: Database info:
Schema::create('contractor', function ($table) {
$table->increments('id');
$table->integer('hba_number')->nullable();
$table->integer('msn')->nullable();
$table->string('type')->default("");
$table->string('name')->default("");
$table->string('address_1')->default("");
$table->string('address_2')->default("");
$table->string('city')->default("");
$table->string('state')->default("");
$table->string('zip')->default("");
$table->string('country')->default("");
$table->string('phone')->default("");
$table->string('website')->default("");
$table->integer('company_id')->nullable();
$table->integer('user_id');
$table->timestamps();
$table->softDeletes();
});
Schema::create('contractor_profile', function ($table) {
$table->increments('id');
$table->integer('contractor_id');
$table->string('tag_line')->default("");
$table->string('story')->default("");
$table->string('area_of_operation')->default("");
$table->text('experience')->default("");
$table->text('education')->default("");
$table->text('insurance_verified')->default("");
$table->timestamps();
$table->softDeletes();
});
The issue may be because you're using a non-standard table name for your Contractor model. Try defining the relationship in your ContractorProfile model by specifying the second parameter to belongsTo:
return $this->belongsTo('Contractor', 'contractor_id');
You may also need to perform the same mapping on the Contractor model as well:
return $this->hasOne('ContractorProfile', 'contractor_id');