Laravel - makeVisible doesn't make hidden attribute visible - php

I have the following code:
$model = new coretable;
log::info($model->all());
$model = $model->makeVisible('id_coretable');
log::info($model->all());
In my lumen log, I get the following result:
[2020-02-26 10:14:19] local.INFO: [{"Internal_key":"TESTKEY_1"},{"Internal_key":"TESTKEY_2"},{"Internal_key":"TESTKEY_3"},{"Internal_key":"TESTKEY_4"},{"Internal_key":"TESTKEY_5"}]
[2020-02-26 10:14:19] local.INFO: [{"Internal_key":"TESTKEY_1"},{"Internal_key":"TESTKEY_2"},{"Internal_key":"TESTKEY_3"},{"Internal_key":"TESTKEY_4"},{"Internal_key":"TESTKEY_5"}]
I would expect the "id_coretable" attribute to be present in the second output from log::info(), but it isnt.
Why is that?
Here is the model of coretable:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class CoreTable extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'coretable';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'Internal_key'
];
protected $hidden = [
'id_coretable',
'created_at',
'updated_at'
];
protected $primaryKey = 'id_coretable';
/**
* Many-To-Many relationship with User-Model.
*/
public function extensiontable_itc()
{
return $this->hasOne('App\extensiontable_itc', 'coretable_id');
}
public function extensiontable_sysops()
{
return $this->hasOne('App\extensiontable_sysops', 'coretable_id');
}
public function inaccessibletable()
{
return $this->hasOne('App\inaccessibletable', 'coretable_id');
}
}
I have no clue why makeVisible() doesnt have any effect on the effect.

The initial model you created does not have any influence on the models received from the all() function. This is a collection of new models with the initial $hidden array.
To change what values are shown, you will have to call makeVisible on the collection you receive:
$model = new coretable;
log::info($model->all());
log::info($model->all()->makeVisible('id_coretable'));
It is also recommended to call the query functions staticaly, this way you don't need to create an initial model:
log::info(coretable::all()->makeVisible('id_coretable'));

Related

Trouble getting hasManyThrough to work in Laravel 9

In my Laravel project I'm having some trouble getting my hasManyThrough relationship to work, these are my models:
Pingtree
BuyerTier
PingtreeEntry
I want to get all of my BuyerTier models through my PingtreeEntry model.
This is my current relationship on my Pingtree model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Pingtree extends Model
{
use HasFactory, SoftDeletes;
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'pingtrees';
/**
* The attributes that should be cast.
*
* #var array<string, string>
*/
protected $casts = [
'is_enabled' => 'boolean',
];
/**
* The accessors to append to the model's array form.
*
* #var array
*/
protected $appends = [
'is_deleting',
];
/**
* Determine if we're editing the model
*
* #return bool
*/
public function getIsDeletingAttribute()
{
return false;
}
/**
* Get the company that owns the model.
*/
public function tiers()
{
return $this->hasManyThrough(
BuyerTier::class, // final model we want to access
PingtreeEntry::class, // intermediate model
'buyer_tier_id', // foreign key on intermediate model
'id', // foreign key on final model
'id', // local key
'pingtree_id' // local key on intermediate model
)->orderBy('processing_order', 'asc');
}
/**
* Get the pingtree entry model
*/
public function pingtree_entry()
{
return $this->belongsTo(PingtreeEntry::class, 'id', 'pingtree_id');
}
/**
* Get the company that owns the model.
*/
public function company()
{
return $this->belongsTo(Company::class);
}
/**
* Get the user that owns the model.
*/
public function user()
{
return $this->belongsTo(User::class);
}
}
And then I query this in my controller:
$pingtree = Pingtree::where('company_id', $company_id)
->where('id', $id)
->with([
'tiers.buyer',
'tiers.pingtree_entry'
])
->first();
This is what my pingtree_entries table looks like:
Right now, for some reason, despite having multiple tiers on my pingtree ID 3, I'm only ever getting 1 result back in my query, and I should be seeing all 4 tiers on my pingtree, what am I missing?

Laravel define a default key with value on Model

In my Laravel 8 project I have a model called Campaign, my front-end though is build in Vue JS so needs to have some keys on a Campaign for contextual purposes, such as opening and closing a dropdown menu when looping over the elements, a database column isn't nessecery for this.
I'd like to add some default key/value pairs to my Campaign model, for example: dropdown_is_open and should have a default value of false.
I came across the default attributes for a model and tried adding this but cannot see my new key on the object, what am I missing?
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Campaign extends Model
{
use HasFactory, SoftDeletes;
/**
* Indicates if the model's ID is auto-incrementing.
*
* #var bool
*/
public $incrementing = false;
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'campaigns';
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'campaign',
'template'
];
/**
* The model's default values for attributes.
*
* #var array
*/
protected $attributes = [
'dropdown_is_open' => false
];
}
Index function in controller:
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$campaigns = Campaign::where('user_id', Auth::id())
->orderBy('created_at', 'desc')
->get();
if (!$campaigns) {
return response()->json([
'message' => "You have no campaigns"
], 404);
}
return response()->json([
'campaigns' => $campaigns
], 200);
}
I expect to see:
{
campaign: 'my campaign',
template: '',
dropdown_is_open: false <-- my key
}
Previously I was doing a foreach in my index function and adding the contextual keys on each item, but this would only show for the index function and I'd have to add it everywhere.
I hope something like below helps.
Change it from my_custom_field to dropdown_is_open key (and from getMyCustomFieldAttribute to getDropdownIsOpenAttribute method-name).
Custom attribute (or Accessor)
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model {
protected $appends = ['my_custom_field'];
public function getMyCustomFieldAttribute()
{
return false;
}
}
The $appends in above is required only,
to ensure that my_custom_field is preset/cached, and even sent as JSON-Response.

How to chain 3 laravel nested models

I am trying to chain 3 models together parent->child->child of child. So I can access it in an eloquent statement.
Parent Model:
class CertificationType extends Model
{
use SoftDeletes;
public $timestamps = true;
protected $table = 'certification_type';
protected $dates = ['deleted_at'];
protected $fillable = array('certification_type_name', 'fa_code', 'icon_image');
protected $hidden = ['created_at', 'updated_at',];
public function certification_type()
{
return $this->hasMany('App\Certification');
}
}
Child Model
class Certification extends Model
{
protected $table = 'certification';
public $timestamps = true;
use SoftDeletes;
protected $dates = ['deleted_at'];
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = array('certification_type_id', 'certification_name', 'certication_date', 'certification_license_number', 'certification_course_length', 'certification_course_description', 'certification_course_topics_list_id');
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'created_at', 'updated_at',
];
public function certification_type()
{
return $this->belongsTo('App\CertificationType',
'certification_type_id');
}
public function certification_course_topics_list()
{
return $this->hasMany('App\CertificationCourseTopicsList');
}
}
Child of Child Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class CertificationCourseTopicsList extends Model
{
protected $table = 'certification_topics_list';
public $timestamps = true;
use SoftDeletes;
protected $dates = ['deleted_at'];
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = array('certification_id', 'certification_topic_description');
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'created_at', 'updated_at',
];
public function certification_course_topics_list()
{
return $this->belongsToMany('App\Certification', 'certification_id');
}
}
The eloquent statement I am using is:
$CertificationTypes = App\CertificationType::orderBy('id',"asc")->with('certification_type')->get()->groupBy('id');
What I have accomplished is CertificationType has a child of Certifications attached in the query. What I need is the 2nd child to be in the query as well:
CertificationType::orderBy('id',"asc")->with('certification_type')->get()->groupBy('id')->with('certification')->get()->groupBy('id');
I also tried:
CertificationType::orderBy('id',"asc")->with('certification_type, certifications')->get()->groupBy('id');
That did not work: Call to undefined relationship [certification_type, certifications] on model [App\CertificationType].
Also tried:
CertificationType::orderBy('id',"asc")->with('certification_type', 'certifications')->get()->groupBy('id');
That did not work: Call to undefined relationship [certifications] on model [App\CertificationType].
Any help would be appreciated!
You need more order in code. I would make three models with proper relations as : belongsTo and hasMany. Then in each view you can use data from model with function of relation.
Example of proper model with relation:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
/**
* Get the comments for the blog post.
*/
public function comments()
{
return $this->hasMany('App\Comment');
}
}
Read more here, that will save your time: https://laravel.com/docs/5.5/eloquent-relationships#one-to-many

I can not add methods to User Model in Laravel 5.4 ..!

I'm using Laravel 5.4. I have the methods I created in the User model. When I want to create an object from the User model and invoke my own methods, I can not get to the methods I added.
The User Model is derived from the Authenticable class at 5.4, which was derived earlier from the Model class. I think the problem is about it. What I really want to do is to set up the belong_to, has_many structure to relate the user model to the other models.
But with the User model I do not do that. What do you recommend ?
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function getMakale()
{
return $this->hasMany(Makale::class, 'user_id', 'id');
}
}
$author = User::first();
return method_exists($author,'getMakale');
//eventually turns false
I believe you are potentially setting an accessor rather than a relationship. In this case I would think you want to name that function something like:
public function haberler()
{
return $this->hasMany(Makale::class, 'user_id', 'id');
}
or public function makales(). Prefixing your function name with get or set will have unintended consequences in Laravel.

Laravel Relationships - access input from other table

I cant get this working. This should be easy, but I cant figure out how to access a users gamer tag from different table using relationships.
Here is my User.php Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'gamertag', 'slug', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
];
// A user has many messages (Chat)
public function chat () {
return $this->hasMany('App\Chat');
}
}
Here is my Chat.php Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Chat extends Model {
protected $table = "chat";
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'message', 'user_id'
];
// A Chat (or message) belong to a user
public function user() {
return $this->belongsTo('App\User');
}
}
And this is how I;m retrieving the messages:
class HomeController extends Controller {
public function index () {
$messages = Chat::orderBy('created_at', 'desc')->get();
return view('layouts.index', compact('messages'));
}
}
Why Im I having trouble getting the gamer tag to display?
#foreach($messages as $message)
<a class="author">{{ $message->user->gamertag }}</a>
#endforeach
/***** Edit***/
This works:
{{ dd($message->user->gamertag) }}
// This does NOT
{{ $message->user->gamertag }}
Try to use eager loading:
$messages = Chat::orderBy('created_at', 'desc')->with('user')->get();
I figured it out! Everything was working here, its just in my chat table, I had inserted a message with no identified user, so user_id = 0, and it was throwing that error off. Silly mistake.

Categories