trying to get some polymorphic relations working in laravel 4.
I have a CoreUserAccount table that looks like so:
core_user_account:
id
profile_id
other columns
I then have 2 other tables core_user_client_profile and core_user_consultant_profile. They both have id fields.
i am trying to link them like so:
In the CoreUserAccount model:
public function profile()
{
return $this->morphTo();
}
And in both the other tables i have:
public function user()
{
return $this->morphOne('CoreUserAccount', 'profile');
}
But i don't seem to be able to get any of the profile data through the user object. Any ideas?
Cheers
EDIT
Here is my core_user_account table:
And here are my 2 different profile type tables core_user_client_profile and core_user_consultant_profile:
Here is my model for core_user_account:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class CoreUserAccount
extends Eloquent
implements UserInterface, RemindableInterface
{
protected $table = 'core_user_account';
protected $hidden = array('password');
protected $guarded = array('id', 'password');
public function profileType()
{
return $this->belongsTo('CoreUserProfileType');
}
public function address()
{
return $this->belongsTo('CoreUserAddress', 'user_account_id', 'id');
}
public function profile()
{
return $this->morphTo();
}
public function getAuthIdentifier() {
return $this->getKey();
}
public function getAuthPassword() {
return $this->password;
}
public function getReminderEmail() {
return $this->email;
}
public function getRememberToken() {
return $this->remember_token;
}
public function setRememberToken($value) {
$this->remember_token = $value;
}
public function getRememberTokenName() {
return 'remember_token';
}
}
And my core_user_client_profile model:
class CoreUserClientProfile
extends Eloquent
{
protected $table = 'core_user_client_profile';
public function profileLanguage()
{
return $this->belongsTo('CoreUserProfileLanguages');
}
public function user()
{
return $this->morphOne('CoreUserAccount', 'profile',null,'profile_id',null);
}
}
And my core_user_consultant_profile model:
class CoreUserConsultantProfile
extends Eloquent
{
protected $table = 'core_user_consultant_profile';
public function profileLanguage()
{
return $this->belongsTo('CoreUserProfileLanguages', 'consultant_profile_id', 'id');
}
public function qualifications()
{
return $this->belongsTo('CoreUserConsultantQualifications', 'profile_id', 'id');
}
public function registration()
{
return $this->belongsTo('CoreUserConsultantRegistrations', 'profile_id', 'id');
}
public function specialities()
{
return $this->belongsTo('CoreUserConsultantProfileSpeciality', 'profile_id', 'id');
}
public function user()
{
return $this->morphOne('CoreUserAccount', 'profile');
}
}
I have read the document pointed out in the comments below and understand i seem to have to have a type column in my DB. But what data needs to be stored here? does it automatically get stored or do i have to store it?
Cheers
You should have to have profile_type, and profile_id columns. In profile_type will be stored values: 'CoreUserConsultantProfile' or 'CoreUserClientProfile'. This fields will be populated automaticlly when you save data.
This is example how save data in polymorph relation.
$profile = CoreUserConsultantProfile::find(1);
$account = new CoreUserAccount();
$profile->profile()->save($account);
So now, profile_id=1, and profile_type = 'CoreUserConsultantProfile'
Related
I'm looking to retrieve all transactions of an event which are created by a booking. I was thinking of using a hasManyThrough relationship. However it returns null. What am I doing wrong?
Event model:
public function booking(){
return $this->hasMany(Booking::class);
}
public function transaction(){
$this->hasManyThrough(Transaction::class, Booking::class);
}
Booking model:
public function event() {
return $this->belongsTo(Event::class);
}
public function user() {
return $this->belongsTo(User::class);
}
public function transaction(){
return $this->hasMany(Transaction::class);
}
Transaction model:
public function booking() {
return $this->belongsTo(Booking::class);
}
public function user() {
return $this->belongsTo(User::class);
}
My tables look like so
I have three tables - users, properties, devices.
users
id
name
properties
id
name
user_id
devices
id
name
property_id
How to define straight relationship to user model from devices model?
class Device extends Model
{
public function user()
{
return $this->....();
}
}
Is it possible to define such relation? Thanks.
Make sure to set all relation in other classes.
class Property extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
class Device extends Model
{
public function property()
{
return $this->belongsTo('App\Property');
}
public function user()
{
return $this->belongsTo('App\User', null, null, 'property');
}
}
You can provide a relation with in 4th parameter of belongsTo method.
//user model
public function role()
{
return $this->belongsTo('App\Role');
}
public function employee()
{
return $this->hasMany('App\Employee');
}
//role model
public function users()
{
return $this->hasMany('App\User');
}
//employee model
public function users()
{
return $this->belongsTo('App\User');
}
//value show using tinker command in command promote
App\User::find(1)->employee;
App\User::find(1)->role;
I think I have found the solution, this is what I end up with.
class Device extends Model
{
public function user()
{
$instance = new User();
$instance->setTable('properties');
$query = $instance->newQuery();
return (new BelongsTo($query, $this, 'property_id', $instance->getKeyName(), 'property'))
->join('users', 'users.id', '=', 'properties.user_id')
->select(DB::raw('users.*')
);
}
}
Hope this will be of help for somebody.
public function index()
{
$query = Activity::orderBy('id','DESC')->with('provinces');
if(!Auth::user()->hasRole('Administer')){
$query=$query->where('province_id', Auth::user()->id);
}
$activities = $query->latest()->get();
return view('activity.index',compact('activities'));
}
How to display owner of a post in laravel admin list display?
My User Model
class User extends Authenticatable implements HasMedia
{
public function activities()
{
return $this->hasMany(Activity::class);
}
}
My Activity Model:
class Activity extends Model
{
protected $guarded = [];
public function user()
{
return $this->belongsTo(User::class);
}
public function provinces()
{
return $this->belongsToMany(Province::class);
}
}
My province Model
class Province extends Model
{
protected $fillable = [ 'title', 'post_id'];
public function activities()
{
return $this->belongsToMany(Activity::class);
}
public function user()
{
return $this->belongsToMany(User::class);
}
}
I want to show the content to the user by province.
And also the admin can see all the content.
please help me i am new in laravel
Based on your comment, you should change your province conditions to:
if (!Auth::user()->hasRole('Administer')) {
$query = $query->where('province_id', Auth::user()->province_id);
}
You have defined that each activity belongs to an user. So can access owner of each activity like this:
$activity->user->name;
And if your activity belongs to a province, you should define your relation in this way:
class Activity extends Model
{
protected $guarded = [];
public function user()
{
return $this->belongsTo(User::class);
}
public function province()
{
return $this->belongsTo(Province::class);
}
}
Also for your Province model:
class Province extends Model
{
protected $fillable = [ 'title', 'post_id'];
public function activities()
{
return $this->hasMany(Activity::class);
}
public function users()
{
return $this->hasMany(User::class);
}
}
And this is best practice to use eager loading for fetching related records. It will look like this one:
$query = Activity::with(['user', 'province'])->orderBy('id','DESC');
Also another hint: try to use better variable names. You can use $activities instead of $query.
I have 5 tables User, Profile, Address,State,City .Need to create relationship between tables.Address has State id , City id and Profile id in the table.Profile has User Id in the table.City has State Id in the table. How to write relationship between table
class City extends Model
{
public function state() {
return $this->belongsTo('App\State');
}
public function addresses() {
return $this->hasMany('App\Address');
}
}
class State extends Model
{
public function cities() {
return $this->hasMany('App\City');
}
public function addresses() {
return $this->hasMany('App\Address');
}
}
class Profile extends Model
{
public function address() {
return $this->belongsTo('App\Address');
}
public function user() {
return $this->belongsTo('App\User');
}
}
class Address extends Model
{
public function profile() {
return $this->belongsTo('App\Profile');
}
public function city() {
return $this->belongsTo('App\City');
}
public function state() {
return $this->belongsTo('App\State');
}
}
// users table
public function profile(){
return $this->hasOne('App\Profile');
}
Generally your model design is true, i have edited a few parts. Try the codes below.
class City extends Model
{
public function state()
{
return $this->belongsTo('App\State');
}
public function addresses()
{
return $this->hasMany('App\Address');
}
}
class State extends Model
{
public function cities()
{
return $this->hasMany('App\City');
}
public function addresses()
{
return $this->hasMany('App\Address');
}
}
class Profile extends Model
{
public function addresses()
{
return $this->hasMany('App\Address');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
class Address extends Model
{
public function profile()
{
return $this->belongsTo('App\Profile');
}
public function city()
{
return $this->belongsTo('App\City');
}
public function state()
{
return $this->belongsTo('App\State');
}
}
class User extends Model
{
public function profile()
{
return $this->hasOne('App\Profile');
}
}
By the way, Laravel relationships add default keys according to your method names. If you have problem about it you can find info from official documents. For example:
$this->belongsTo('App\Model', 'foreign_key', 'other_key');
as #mustafa.akcoban says...
When you use belongsTo Eloquent will work as follow
$this->belongsTo('App\City', 'foreign_key', 'other_key');
// foreign_key = is the primary key in the related model, by default 'id' for Eloquent
// other_key = is the field in the current model that contains the id of the other model, by default othermodelname_id for Eloquent
// For eg. 'App\City', 'id', 'city_id'
When you use hasMany Eloquent works as follow
$this->hasMany('App\Model', 'currentmodel_id', 'primary_key');
// currentmodel_id = is the field that contains the current model primary key in the related model
// primary_key = is the current primary key model that will be in the other model, by default id for Eloquent
// For eg. 'App\City', 'state_id', 'id'
Remember you can or can't use second and third parameter, if something is wrong Laravel dump will tell you what column was not found in the table, and you will can fix.
Please try and practice this, and let me know how it works :)
Users table structure: users
id, name, username, password, created_at, updated_at
Article table structure: article
id, title, content, created_at, updated_at
Relationship table: article_user
id, article_id, user_id, is_active, created_at, updated_at
Tags
id, name, user_id, created_at, updated_at
Relation of pivot table article_user with tags. table: article_user_tag
tag_id, article_user_id
class User extends Model
{
protected $fillable = ['name','username','password'];
public function articles()
{
return $this->belongsToMany('App\Article')->withPivot('is_active')->withTimestamps();
}
public function tags()
{
return $this->hasMany('App\Tag');
}
}
class Article extends Model
{
protected $fillable = ['title','content'];
public function users()
{
return $this->belongsToMany('App\User')->withPivot('is_active')->withTimestamps();;
}
public function tags()
{
return $this->belongsToMany('App\Tag');
}
}
class Tag extends Model
{
protected $fillable = ['title','content'];
public function articles()
{
return $this->belongsToMany('App\Article');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
I want to connect these table so I can access like this or similar format
$user->articles()->first()->tags;
and should be able to create/update as well, smth like this
$user->articles()->first()->create(['title'=>'testing','content'=>'content'])->attach(['tag_id_1','tag_id_2','tag_id_3']);
Any help is much appreciated
Try this:
class User extends Model
{
protected $fillable = ['name','username','password'];
public function articles()
{
return $this->hasMany('App\ArticleUser')->with('article');
}
public function tags()
{
return $this->hasMany('App\Tag');
}
}
class ArticleUser extends Model
{
public funciton article()
{
return $this->belongsTo('App\Article');
}
public function user()
{
return $this->belongsTo('App\User');
}
public function tags()
{
return $this->belongsToMany('App\Tag');
}
}
class Article extends Model
{
protected $fillable = ['title','content'];
}
class Tag extends Model
{
protected $fillable = ['title','content'];
public function articles()
{
return $this->belongsToMany('App\ArticleUser')->with('article');
}
public function user()
{
return $this->belongsTo('App\User');
}
}