I'm using Laravel Auditing Package to trace changes on my models.
I want to get a specific column of the foreign key in it's primary table before recording the events (create, update, delete) in the audit table.
There is a way the package helps get all the attribute of the foreign key, it's called Audit Transformation but it generates an error for me when displaying the details in the table i want to know if there's any eloquent model method to get the specific column info i need instead of using getattribute() method which gets the entire row of the item_id.
Audit Transformation Method
public function transformAudit(array $data): array
{
if (Arr::has($data, 'new_values.item_id')) {
$data['old_values']['item_name'] = Item::find($this->getOriginal('item_id'));
$data['new_values']['item_name'] = Item::find($this->getAttribute('item_id'));
}
return $data;
}
This is how it's stores in the database ephasis on the item_name.
{"item_id":"1","qty_received":"2","delivered_by":"John",
"received_by":"Abi","supplier":"Stores","date":"2019-11-26","item_name":{"item_id":1,"item_name":"Toner","colour":"Black","status":"Active",
"created_at":"2018-10-25 17:55:26","updated_at":"2018-10-25 17:55:26"}}
And this is the Item table schema
So in my scenario i'd want to store the item_name as Toner not the entire row of the item_id
Any suggestion will be welcomed, thanks in advance.
Add ->item_name->item_name after the function of Find.
if (Arr::has($data, 'new_values.item_id')) {
$data['old_values']['item_name'] = Item::find($this->getOriginal('item_id'))->item_name->item_name;
$data['new_values']['item_name'] = Item::find($this->getAttribute('item_id'))->item_name->item_name;
}
Related
When I want to delete a row from table I want to check the tables which use the id of this row. If used then it doesn't allow to delete.
You can simply check whether specific column(containing other table's key) in the row is empty or null and if it is empty then delete the row otherwise skip it.
You have two ways in which you can do it-
using eloquent get the row by primary key and check the property on collection.
write a stored procedure in the database and call it in your Laravel code.
You can use the deleting model event to check if the relationships exist. If they do, then prevent the delete.
https://laravel.com/docs/5.7/eloquent#events
If you create an observer for your model, you can use something like this:
public function deleting($model)
{
if($model->someRelation->count()) { // replace ->someRelation with whatever you want to check
return false; // prevent delete
}
if($model->anotherRelation->count()) {
return false; // prevent delete
}
}
I have two table
1. Bog_post
2. blog_image
Now I want only one image from blog_image table.
I also save post id in blog_image table.
how can i do this query in laravel ?
Create a model as "BlogImage" and edit it.
class BlogImage extends Model
{
protected $table = 'blog_image';
}
Then create a query with this model.
$blog_image = BlogImage::where('post_id',$post_id)->pluck('image')->first();
You can get just "image" column data in this way, as you want.
Also you can set releationship with this two tables. Here is documentation
I have a table content. So when I retrive anything from that table using laravel eloquent, I need to set a global where clause Content::where('is_playlist', 1)->get();, so that every time I retrieve data from that table, I should automatically filtered with that particular where clause.
You can create a scope function in the model to filter that out e.g:
public function scopePlaylist($query)
{
return $query->where('is_playlist', 1);
}
This means you can easily call, Content::playlist()->get() and you'll have only playlist content.
I hope this is useful?
I have a model (Client) with a hasMany relationship to another (Client_option).
The two tables are in different databases (so there is a list of clients, and then each client has their own database with an options table within).
In my Client class I want my options() method to return the entire contents of the options table (it knows which client db to look for). As it is I get an error because the column client_id does not exist in the options table. I can of course create that column and populate every row with the client's id, but I'd only be doing it to keep Eloquent happy so would rather avoid that little messiness.
Thanks in advance for any input!
Geoff
This will allow you to work with it as a relation, call it as dynamic property $user->options, bulk save with push method and so on:
public function options()
{
// it will use the same connection as user model
$options = ClientOption::on($this->getConnectionName())->get();
// if options model has its own, then simply
// $options = ClientOption::get();
$this->setRelation('options', $options);
return $options;
}
public function getOptionsAttribute()
{
return (array_key_exists('options', $this->relations))
// get options from the relation, if already loaded
? $this->getRelation('options')
// otherwise call the method and load the options
: $this->options();
}
I've got a situation in a project where I need to form a relationship between a primary key on one table and an indexed column (not the primary key) on another. Here's a sample of the database layout:
courses table
id
level
resources table
id
courses_resources table
course_level
resource_id
In my CourseResource model I have the following:
public function courses(){
return $this->belongsToMany('Course', 'courses_resources', 'resource_id', 'course_level');
}
Which works fine.
Then in my Course model I have:
public function resources(){
return $this->belongsToMany('CourseResource', 'course_resources', 'course_level', 'resource_id');
}
Which doesn't work. When I look at the last query performed on the database, it appears Laravel is searching the course_level column using the course's ID. That makes sense, but is there any way to use the level column for this relationship?
Eloquent BelongsToMany depends on PKs, so there is no way to do that with its methods.
You need custom relation object for this, that will check for given field, instead of primary key.
A quick and hacky solution would be this:
// Course model
public function getKey()
{
$relation = array_get(debug_backtrace(1, 2), '1.object', null);
if (method_exists($relation, 'getForeignKey')
&& $relation->getForeignKey() == 'courses_resources.course_level')
{
return $this->getAttribute('level');
}
return parent::getKey();
}
However if you would like to use it in production, do some extensive testing first.