I'm trying to use Laravel to access some data from the database. I have setup my model, which works fine, however I'm trying to fetch some data from another table by creating a method within the model which fetches the data and sets a property of the model equal to the fetched data.
To fetch the data, I'm trying to use the $this->id property to fetch this row's ID and use it to fetch data from another table (eg: SomeOtherModel::where('other_id', '=', $this->id)->get();)
However, none of the data from the database seems to have been fetched by the model at this point (eg: $this->id is null). My constructor looks like so:
public function __construct() {
parent::__construct();
$this->other_data = $this->getOtherData();
}
Is there any way to call the $this->id property from the database so I can use it within the model itself?
Your syntax seemed to me wrong:
SomeOtherModel::where('other_id', '=', $this->id)->get();
Can you try this:
SomeOtherModel::where('other_id', $this->id)->get();
Reference: https://laravel.com/docs/5.1/eloquent#retrieving-single-models
I hope this helps .
The solution is explained here:
class ExampleModel extends Model {
protected $appends = ['otherdata'];
public function getOtherdataAttribute() {
return $this->getOtherData();
}
}
Related
I'm currently trying to use Laravel Relationships to access my achievements Model using User model, I use this relationship code:
public function achievements()
{
return $this->hasMany('App\Models\User\Achievement');
}
I can easily make some eloquent queries, however I can't access any method that I created there, I can't access this method:
class Achievement extends Model
{
public function achievementsAvailableToClaim(): int
{
// Not an eloquent query
}
}
Using the following code:
Auth::user()->achievements()->achievementsAvailableToClaim();
I believe that I am using this Laravel function in the wrong way, because of that I tried something else without using relationship:
public function achievements()
{
return new \App\Models\User\Achievement;
}
But that would have a performance problem, because would I be creating a new class instance every time I use the achievements function inside user model?
What would be the right way of what I'm trying to do?
it's not working because your eloquent relationship is a hasMany so it return a collection. you can not call the related model function from a collection.
you can var dump it on tinker to understand more what i mean.
You can use laravel scopes.Like local scopes allow you to define common sets of constraints that you may easily re-use throughout your application.
In your case you use this like, Define scope in model:
public function scopeAchievementsAvailableToClaim()
{
return $query->where('achivement_avilable', true);
}
And you can use this like :
Auth::user()->achievements()->achievementsAvailableToClaim();
I'm trying to delete one row of data from my sql table called "cart".
It seems to me that it can not find the id called "cartid". im using a program called insomnia and it wont take my input it feels like.
it is gettting a error that is called :"MethodNotAllowedHttpException"
im using laravel 5.4, it is a requirement for me.
i have other functions that work and i do not understand why this one does not.
https://imgur.com/a/T0aOwJF
some snapshots from my code
i have tried to use
Route::delete('cart-remove/{id}', 'CartController#delete');
and alot more
this is in my 'api.php' file:
Route::delete('cart-remove', 'CartController#delete');
this is in my file called 'CartController':
class CartController extends Controller {
public function delete($id) {
DB::table('cart')->where('cartid', '=', $id)->delete();
return response($id, 200);
}
}
i want to get the id from my program called 'insomnia' to remove that id in my sqlite database.
Use the model's destroy method when deleting entries from the database:
use App\SomeModel;
class SomeController extends Controller {
public function destroy($id) //or delete($id)
{
SomeModel::destroy($id);
return response($id, 200);
}
}
For followers relation on same User model I used belongsToMany()
public function followers() {
return $this->belongsToMany('App\User', 'followers', 'follow_id', 'user_id');
}
But since I am using this for chat list on load with vue I am on page load passing json_encode(auth()->user()->followers) which works as I needed.
But when I am lets say using only some columns like:
->select(['id', 'name', 'avatar']);
I have additional method for avatar:
public function image() {
return $this->avatar || 'some-default-image';
}
How can I pass that as well for each of many? Without withDefault method..
Try adding this in your User model
class User extends Model {
protected $appends = ['image'];
// other stuff..
}
this will forcefully inject your computed property ie. image in every User model instance but for it work you have to name your method (or create another) like getImageAttribute()and not simply image()
// getter for `image` property in user model object
public function getImageAttribute() {
return $this->avatar || 'some-default-image';
}
What you are looking for is the Accessor function:
Laravel Accessors and Mutators
Basically you define an accessor function in your model:
public function getAvatarAttribute($value)
{
return $value || 'some-default-image';
}
Then when you access the avatar property using ->avatar, the accessor function will get called and you will get the computed value.
====================================================================
The comment has words limit.
You have followers table where each follower is a User. You use relationship to filter all followers which are a group of Users. You wanted getInfo() to be called on each follower so that the additional data is appended to your JSON structure.
In that case, you don't need to filter through each follower and call getInfo() yourself. You use accessor method, put your code in getInfo() into an accessor method, and modify $appends array in your User model, then then JSON data will be automatically appended.
public function getUserInfoAttribute()
{
$userInfo = ... //use logic in your original getInfo method
return $userInfo;
}
Then you add user_info into your User model's $appends array:
protected $appends = ['user_info'];
This way, your user_info will be automatically included when your instance is serialized into JSON.
Like I said in the comment, you should check out:
Appending Values To JSON
for more information.
As to APIs , whether you are using Vue or React or anything, when passing JSON data for your frontend code to consume, you are basically creating apis. FYI:
Eloquent: API Resources
I'm sure this is a totally simple question but for the life of me I'm stuck here- we're using Eloquent outside of Laravel due to PHP restrictions. I have a support ticket tracking app that I'm trying to update.
The data structure of this app is such that each ticket is assigned a UUID on submission and a table with that UUID as its name is generated and all changes to the ticket are tracked as new entries in that table.
Following some tutorials on Eloquent I got our models and controllers set up and working but for each one I see that I'm defining the table name in the model itself. IE our ticket model is
namespace Models;
use \Illuminate\Database\Eloquent\Model;
class Ticket extends Model {
protected $table = 'tickets';
protected $fillable = [table columns here];
}
and anything called in the tickets controller correctly and successfully reads and writes data to our tickets table.
So... my question is: how would I go about reading/writing/creating/deleting those previously mentioned UUID tables?
I've tried the built in table selector (ie- DB::table(uuid here) and DB::setTable(uuid here) but to no avail. I get Fatal error: Call to undefined method Models\Database::setTable()
What I'm after is a model/controller that I can reuse for ANY dynamically-named table.
You could create a generic model and dynamically set the table name, like this:
namespace Models;
use \Illuminate\Database\Eloquent\Model;
class FormerUUIDTicket extends Model {
protected $table = 'some_table';
protected $fillable = [table columns here];
}
class SomeController
{
public function someAction()
{
$uuid = $_POST['uuid_field']; //some uuid, the table name
$model = new FormerUUIDTicket;
$model->setTable($uuid);
return $model->get(); //do anything using eloquent with proper table
}
}
Make sure that you always set the table name before use, or it will fail. Don't use static function either, for the same reason.
I'm starting my first Laravel project. I set up and tested all the relationships between tables and all of them look fine but one 1-N relationship. I cannot find the error, could you please help me?
Tables:
User:
*id
*username
Feeling:
*id
*name
*user (it points to User:id)
Class User
<?php
class User extends Eloquent {
protected $table = 'User';
public function feelings() {
return $this->hasMany('Feeling', 'user');
}
}
Class Feeling
class Feeling extends Eloquent {
protected $table = 'Feeling';
public function user() {
return $this->belongsTo('User','user');
}
}
If I execute:
$feeling = Feeling::find(1);
echo($feeling->user->username);
I get an error "Trying to get property of non-object".
If I execute
$feeling = Feeling::find(1);
It prints the Json array of the feeling object and if I execute
$feeling = Feeling::find(1);
echo($feeling->user);
It prints "1". So I'm getting the user ID of the database, but not the user object. I would like to get the user object instead.
Thank you very much.
Problem:
Everything is fine but you have used user as your local key and that's why the confusion because, when you call $feeling->user the magic method __get() is called which is available in the Illuminate/Database/Eloquent and it; as given below:
public function __get($key)
{
return $this->getAttribute($key);
}
The getAttribute() method looks several places for the key and sequentially it looks into the Model itself at first and then looks into the relationship array and then at last checks if the key for examaple in your case user exists as a method in the Model which is Feeling in your case, then it gets the related model and finds the key value.
Hence, your Feeling has a field as user so before it goes to the related model it just finds the field in current Model's attributes so it thinks that, user field has been requested for and you get the numeric id instead if related model instance.
Solution:
Solution is pretty simple, change the related field name (user) to anything else, better is user_id but you are free to use anything but make sure that doesn't create any further confusions. So, if you change it to user_id then make changes to your both models, for example:
public function user() {
return $this->belongsTo('User','user_id');
}
But, if you use user_id then you may omit the second argument from both model's relationship method, so you may write:
// Feeling
return $this->belongsTo('User');
// User
return $this->hasMany('Feeling');