How to implement this relationship in laravel? - laravel

i have 4 table
inst
id
subject
report
id
subject
object
id
type
container
id
obj_id
i want with obj_id of container table, achieve the The corresponding object record.
then if type of object = 1, fetch data from inst table or type = 2, fetch data from report table

based on your information,
you can do like #Mahfuz Shishir answer
or
create new appends attribute inside Object Model
protected $appends = ['data'];
public function getDataAttribute()
{
if($this->attributes['type'] == 1) {
return Inst::where('inst_column', $this->attributes['object_column_to_match']); //this just sample
} else {
return Report::where('inst_column', $this->attributes['object_column_to_match']); //this just sample
}
}

The relation looks like.
In your Object.php Model
public function containers()
{
return $this->hasMany('App\Container', 'foreign_id');
}
And in your Container.php Model
public function object()
{
return $this->belongsTo('App\Object', 'foreign_id');
}
You provide little information. Implement rest of the controller code in your own sense. Or put some code that you have tried.

Related

Laravel, property not found

Trying to get property from a object in laravel. I have this:
public function index()
{
$firmen = Companies::all();
$allcountcompanies = Companies::count();
$agent = Agent::find($firmen->agent_firma_id);
return view('companies',compact(['firmen'],['allcountcompanies'],['agent']));
}
The Exeption gives me that:
Property [agent_firma_id] does not exist on this collection instance.
But when i put the id eg 1001 it shows corrent entry in db field.
What i0'm doing wrong?
Info:
CompaniesController.php (table: br_firma)
AgentController.php (table: br_firma_agents)
Table "br_firma_agents" contains a foreign_key from table "br_firma".
You are getting id from collection.
$firmens = Companies::all();
it return collection you may be use it useing loop and get one by one data as
for($firmens as $firmen){
$agent = Agent::find($firmen->agent_firma_id);
}
Or you create relation between Company and agent as,
In company model define relation as
public function agents(){
return $this->hasMany(Agent::class);
}
and in agent model define relation as
public function company(){
return $this->belongsTo(Companies::class);
}
and then call it as in controller,
$data = Companies::with('agents')->get();
You are trying to access an agent_firma_id from a collection of companies, you could first use a loop on that collection,or use an index on that collection,
you could try
$firmens = Companies::all();
foreach($firmens as $firmen){
$agent = Agent::find($firmen->agent_firma_id);
}

Get data from row inside model?

I need to set a morphed model dynamically based upon the row:
On the model I set it inside:
public function getMorphClass()
{
}
How can I get the item type from the row in the query? Something like:
public function getMorphClass()
{
return $this->type; //currently null but want row's type value
}

Get all badges with user progress if any

I have a many to many relationship between users and achievements. Table layout is similar to this.
users
-id
-first_name
-last_name
-email
acheivements
-id
-type-name
-description
achievement_user
-id
-acievement_id
-user_id
-is_complete (boolean)
-percentage_complete (integer)
-completed_at
I can get the bulk of the stuff I want such as all achievements with type = badge for a user that are in the pivot table. I can also get a list of all the achievements that have type = badge. Where I am stuck is trying to get all achievements with type = badge along with is_complete, percentage_complete, completed_at for that given user. So if there are 8 total badges and they have started 3 of them I would want to return 8 records where 3 of them would have the information from the pivot table. I know I could grab all badges and loop through them to add on additional information but I know there is a eloquent way that would be easier.
Thank for any help.
This is in response to you recent comment.
To achieve what you want, I have introduced a new method on the User model called achievementsblock, which uses php array_map method.
I have not tested the code, but you should get the idea.
//in User model
public function achievements()
{
return $this->belongsToMany('App\Achievements')->withPivot('is_complete', 'percentage_complete', 'completed_at');
}
//in User model
public function achievementsblock()
{
$all_achievements = Achievement::all();
return array_map(function($temp_achievement){
$achievement_ids = $this->achievements()->pluck('id');
$new_temp = new \stdClass();
$new_temp->type_name = $temp_achievement->type_name;
$new_temp->description = $temp_achievement->description;
if(in_array($temp_achievement->id, $achievement_ids)){
$user_achievement = $this->achievements()->where("achievements.id","=",$temp_achievement->id)->first();
$new_temp->is_complete = $user_achievement->is_complete;
$new_temp->percentage_complete = $user_achievement->percentage_complete;
$new_temp->completed_at = $user_achievement->completed_at;
}
else {
$new_temp->is_complete = 0;
$new_temp->percentage_complete = 0;
$new_temp->completed_at = null;
}
return $new_temp;
}, $all_achievements);
}
In your controllers, you can get the achievementsblock for a user as follows:
$user_achievement_blocks = User::first()->achievementsblock();
On your belongsToMany relationship, use the withPivot function as follows:
//in User model
public function acheivements()
{
return $this->belongsToMany('App\Acheivement')->withPivot('is_complete', 'percentage_complete', 'completed_at');
}
//in Acheivement model
public function users()
{
return $this->belongsToMany('App\User')->withPivot('is_complete', 'percentage_complete', 'completed_at');
}
You need to learn about whereHas method which lets you query on relationship while getting results
In User model
// create achievements relationship
public function achievements()
{
return $this->belongsToMany(Achievement::class)
->withPivot('is_complete', 'percentage_complete', 'completed_at');
}
//then query it like shown below.
$achievements= $user->achievements;
Read more here

Laravel 5.2: Accessor on a column with camel case in its name

Im trying to use a laravel accessor to modify the content of a column when retrieving it. Im doing it like this:
On my model:
public function getMyColumnAttribute($value)
{
//Modify the content
return $value.'tttt';
}
On my controller:
public function test()
{
return MyModel::select('my_column')->find(1);
}
This works perfectly when the column in my DB is named 'my_column', but my entire database use camel case, so the actual name of the column is myColumn and the accessor just dont work in that case, I mean, it does return the value of my column, but without the modification I did in the accessor. I think it must be a way to it but I cant find how.
Thanks for the help
EDIT
I just realized that while this doesnt work: (myColumn is of type time on a MySql DB)
public function test()
{
return MyColumn::select('myColumn')->find(1);
//returns {"myColumn":"08:00:00"}
}
This acctually do what I expect
public function test()
{
$result = MyColumn::select('myColumn')->find(1);
return $result->myColumn;
// returns 08:00:00tttt
}
accessor doesnt modify the column raw data, it is used on create a new Attribute
use Mutator, save the modifyed raw data to db
use Accessor, get the raw data and modify it and assign to a new attribute
in your case
public function getMyColumnAttribute()
{
//Modify the content
return $this->attributes['type_column_name_here'] . 'tttt';
}
public function test()
{
// myColumn = the column name
$result = MyColumn::select('myColumn')->find(1);
// this is return the column value 08:00:00
return $result->myColumn;
// this will return accessor value 08:00:00tttt
return $result->my_column;
}
getMyColumnAttribute will convert to my_column

How to setup conditional relationship on Eloquent

I have this (simplified) table structure:
users
- id
- type (institutions or agents)
institutions_profile
- id
- user_id
- name
agents_profile
- id
- user_id
- name
And I need to create a profile relationship on the Users model, but the following doesn't work:
class User extends Model
{
public function profile()
{
if ($this->$type === 'agents')
return $this->hasOne('AgentProfile');
else
return $this->hasOne('InstitutionProfile');
}
}
How could I achieve something like that?
Lets take a different approach in solving your problem. First lets setup relationship for the various models respectively.
class User extends Model
{
public function agentProfile()
{
return $this->hasOne(AgentProfile::class);
}
public function institutionProfile()
{
return $this->hasOne(InstitutionProfile::class);
}
public function schoolProfile()
{
return $this->hasOne(SchoolProfile::class);
}
public function academyProfile()
{
return $this->hasOne(AcademyProfile::class);
}
// create scope to select the profile that you want
// you can even pass the type as a second argument to the
// scope if you want
public function scopeProfile($query)
{
return $query
->when($this->type === 'agents',function($q){
return $q->with('agentProfile');
})
->when($this->type === 'school',function($q){
return $q->with('schoolProfile');
})
->when($this->type === 'academy',function($q){
return $q->with('academyProfile');
},function($q){
return $q->with('institutionProfile');
});
}
}
Now you can access your profile like this
User::profile()->first();
This should give you the right profile. Hope it helps.
you can do this by use another method please check this:
a blog Post and Video model could share a polymorphic relation to a
Tag model. Using a many-to-many polymorphic relation allows you to
have a single list of unique tags that are shared across blog posts
and videos. First, let's examine the table structure:
https://laravel.com/docs/5.4/eloquent-relationships#many-to-many-polymorphic-relations
Looks like that should be $this->type rather than $this->$type - since type is a property, not a variable.

Resources