unable to get attributes in an accessor method - laravel eloquent - php

Okay I want to have custom field that does not exist as a column in my db table.
I followed, last part :
http://laravel.com/docs/4.2/eloquent#accessors-and-mutators
My model code:
class Car extends Eloquent{
protected $fillable = array('driverID', 'fuelRemaining');
protected $appends = array('is_driver');
public function user(){
return $this->belongsTo('user');
}
public function getIsDriverAttribute(){
return ($this->attributes['driverID'] == Auth::user()->id);
}
}
Car table:
Schema::create('cars', function(Blueprint $table)
{
$table->increments('id');
$table->integer('driverID');
$table->integer('fuelRemaining');
$table->mediumtext('desc');
$table->timestamps();
});
As you can see i want an extra field which is "is_driver" to be returned, but when I run this, this field is used to determine whether current signed in user is the driver himself by comparing the IDs.
it will output this error:
Undefined index: driverID
Not sure what am I doing wrong here, please advice.

Ah I have found why. This is a reference for future readers
In my controller I only get these two
$car = Car::where('fuelRemaining', 0)->get(array('id', 'desc'));
When i added authorID to the get array
$car = Car::where('fuelRemaining', 0)->get(array('id', 'desc', 'authorID'));
I am able to get the authorID attribute in my custom accessor mentioned in the question.

Related

One to Many Relationship Laravel cannot display the related data

I have two models called DataKelurahan and RegistrasiPasien and have a one-to-many relationship, but I can't access the relationship.
I have made a form for adding patient and save it to the registrasi_pasiens table and it works well. but when I try to display the relation data, it doesn't work properly.
In the registrasi_pasiens table, I have 1 record with kelurahan_id = 3. Then, I try to access it via php artisan tinker with these command:
$kelurahan = App\Domain\DataKelurahan\Models\DataKelurahan::find(3) works fine and data is exist.
$pasien = App\Domain\RegistrasiPasien\Models\RegistrasiPasien::find(2007000001) works fine and the data is exist with kelurahan_id = 3
$kelurahan->pasiens the result is null. Shouldn't it show the pasien data that has kelurahan_id = 3?
$kelurahan->pasiens->nama and the result is like this PHP Notice: Trying to get property 'nama' of non-object in D:/PROFESSIONAL/PROJECT/WEB DEVSeval()'d code on line 1 => null
I don't have any idea what's wrong with my codes. Much appreciate for your help guys.
Below are the models that I have made:
DataKelurahan.php
<?php
namespace App\Domain\DataKelurahan\Models;
use Illuminate\Database\Eloquent\Model;
use App\Domain\RegistrasiPasien\Models\RegistrasiPasien;
class DataKelurahan extends Model
{
protected $fillable = ['nama_kelurahan', 'nama_kecamatan','nama_kota'];
public function pasiens(){
return $this->hasMany('RegistrasiPasien');
}
}
RegistrasiPasien.php
<?php
namespace App\Domain\RegistrasiPasien\Models;
use Illuminate\Database\Eloquent\Model;
use App\Domain\DataKelurahan\Models\DataKelurahan;
class RegistrasiPasien extends Model
{
protected $fillable = [
'nama',
'alamat',
'telepon',
'rt',
'rw',
'tgl_lahir',
'jenis_kelamin'
];
public function kelurahan(){
return $this->belongsTo('DataKelurahan');
}
}
And below are my database tables:
data_kelurahans
Schema::create('data_kelurahans', function (Blueprint $table) {
$table->increments('id');
$table->string('nama_kelurahan');
$table->string('nama_kecamatan');
$table->string('nama_kota');
$table->timestamps();
});
registrasi_pasiens
Schema::create('registrasi_pasiens', function (Blueprint $table) {
$table->increments('id');
$table->integer('kelurahan_id')->unsigned();
$table->string('nama');
$table->string('alamat');
$table->char('telepon', 15);
$table->integer('rt');
$table->integer('rw');
$table->date('tgl_lahir');
$table->string('jenis_kelamin');
$table->timestamps();
});
Schema::table('registrasi_pasiens', function (Blueprint $table){
$table->foreign('kelurahan_id')->references('id')->on('data_kelurahans')->onDelete('cascade');
});
From Docs:
Eloquent will automatically determine the proper foreign key column on
the model. By convention, Eloquent will take the "snake case"
name of the owning model and suffix it with _id.
So, Eloquent probably got your foreign key name wrong so you must override the foreign key by passing additional arguments to the hasMany/belongsTo method:
public function pasiens(){
return $this->hasMany('RegistrasiPasien','kelurahan_id');
}
public function kelurahan(){
return $this->belongsTo('DataKelurahan','kelurahan_id');
}

Unable to use `lists` in many to many relationship

My Laravel version is 5.5.13.
I created a many to many relationship between User model and Pet model. Pets can belong to multiple users.
I am trying to do in my update method in controller, get a list of all associated user ids. So I tried:
public function update(Request $request, Pet $pet)
{
dd($pet->users()->lists('id'));
$pet->update($request->all());
return response()->json($pet, 200);
}
However I get:
Call to undefined method Illuminate\Database\Query\Builder::lists()
It seems there is no lists().
If I do dd($pet->users()) it gives no error and shows a lot of information.
*May you please help to get this lists() to work.
My relationship in Pet model is:
public function users()
{
return $this->belongsToMany('App\User');
}
And my relatinship in User model is:
public function pets()
{
return $this->belongsToMany('App\Pet');
}
Here is my migration for the pivot:
Schema::create('pet_user', function (Blueprint $table) {
$table->integer('pet_id')->unsigned()->index();
$table->foreign('pet_id')->references('id')->on('pets')->onDelete('cascade');
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
list() is no more available in Laravel. Alternatively you can use pluck() and pluck all items like this pluck()->all();
pluck('key')->all();
pluck()->all();
Reference doc
laravel has deprecated the lists() method use pluck instead.
https://laracasts.com/discuss/channels/laravel/lists-deprecated-replacement

Laravel Get Username based on user_id from another table

I am trying to use (and get my head around Eloquent) to get a username from the user table, based on the user_id I have stored in another table, but everything I try seems to be throwing up road blocks.
I've tried a loop (foreach) and then using what I thought was the correct syntax for Eloquent to get what I need, but it's not working.
I've done this using views before and it works, but doesn't work in the Controller.
Hoping someone here can show me how this is supposed to work, based on my code.
Lead Model:
class Lead extends Model
{
protected $fillable = [
'bname', 'tname'
];
public function user()
{
return $this->belongsTo(User::class);
}
}
LeadController
class LeadController extends Controller
{
use Helpers;
public function index(Lead $leads)
{
$leads = $leads->get();
//foreach $leads, get the username from 'user_id' from user table
//return the leads, without the user_id, but with the username
return $leads;
}
}
Function in User.php (class User extends Authenticatable)
public function leads()
{
return $this->hasMany(Lead::class);
}
Lead Migration
Schema::create('leads', function (Blueprint $table) {
$table->increments('lead_id')->nullable(false);
$table->string('bname')->nullable(false);
$table->string('tname')->nullable();
$table->integer('user_id')->index();
$table->timestamps();
});
Hopefully this makes sense to you and someone can help me learn :)
Thanks.
You can use
$user = User::where('id', $userid)->first();
in your controller, assuming you have the userid stored in the variable and 'id' is you column name in the user table. You have the User Model as a result and can access e.g. the username with
$name = $user->username

Dealing with Eloquent relationships in Laravel 5.3

I have the following tables created using Schemas:
Schema::create('typen', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
});
Schema::create('auktionen', function (Blueprint $table) {
$table->increments('id');
$table->integer('typ')->unsigned();
$table->foreign('typ')->references('id')->on('typen');
});
The table typen is only created once at contains fixed values:
Typen
id| name
1 | Typ 1
2 | Typ 2
...
Those values are constant, no more will be added during the application lifetime. So every Auktion I create should be associated with one Typ.
I created the model for Auktion and thought of it as a one-to-one relationship (is this correct?).
I would like to create an Auktion with a given Typ using Eloquent queries like this:
$thetyp = App\Typ::where("id", "=", 1)->first();
$auktion->typ()->associate($thetyp);
and fetch the name of the Typ of my Auktion:
$auktion->typ->name;
Currently my model looks like this for Auktion:
public function typ()
{
return $this->hasOne('App\Typ', 'typ');
}
which is not working. I already tried setting different relationships but I just end in different error codes ranging from undefined methods (associate() to an error where an SQL statement failed trying to update my typen table (when using save() - which I really do not want to).
Can someone clarify this problem for me and explain which relationship I have to use?
EDIT1: As mentioned in a comment I already tried using belongsTo in Auktion model
public function typ()
{
return $this->belongsTo('App\Typ', 'typ');
}
which results in Undefined property: App\Auktion::$typ when calling
$thetyp = App\Typ::where("id", "=", 1)->first();
$auktion->typ()->save($thetyp);
and when calling $auktion->typ->name; in
Trying to get property of non-object
EDIT2:
I just figured that
echo $auktion->typ()->first()->name;
is indeed working. But referring to this answer this should be the same as
echo $auktion->typ->name;
What exactly am i doing wrong?
EDIT3:
I tried using suggested code:
$thetyp = App\Typ::find($typ);
$auktion->typ->save($thetyp);
After I navigated to the view ehere I run the code I got this:
I got this the second time today, somwhow out of nowhere
Here is some code enhancement:
$thetyp = App\Typ::where("id", "=", 1)->first();
$auktion->typ()->save($thetyp);
To:
//Will return null if Model is not found
$thetyp = App\Typ::find(1);
//You actually have to retrieve the relationship, because calling typ()
//will only retrieve the Relationship query
$auktion->typ()->get()->save($thetyp);
The problem is that the relationship is defined backwards. You need to make Auction belongTo Type, and change Type to hasMany Auctions. The statement would read:
"A Type has many Auctions. An Auction has one Type".
Here are the classes (in English, sorry, my German is bad :( so I just did it in English) with the migrations:
-Auction class:
class Auction extends Model
{
protected $table = 'auction';
public function type()
{
return $this->belongsTo('App\Type');
}
}
-Auction migration:
Schema::create('auction', function(Blueprint $table){
$table->increments('id');
$table->integer('type_id')->references('id')->on('type')->nullable();
$table->string('title')->nullable();
$table->string('description')->nullable();
$table->timestamps();
});
-Type class:
class Type extends Model
{
protected $table = 'type';
public function auction()
{
return $this->hasMany('App\Auction');
}
}
-Type migration:
Schema::create('type', function(Blueprint $table){
$table->increments('id');
$table->string('name');
$table->timestamps();
});
First, you can create a Type object (or insert it with a query) so we can have a Type row that we can relate to an Auction object/entry, and do the following:
//Example of Type obj creation
$type = new Type();
$type->name = 'Type #1';
//Don't forget to save
$type->save();
//OR find/retrieve a Type obj
//Where $id is the id of the Type obj, else the obj will be null
$type = Type::find($id);
$auction = new Auction();
$auction->title = 'Title #1';
$auction->description = 'Test description';
$auction->type_id = $type->id;
//Don't forget to save
$auction->save();
Now later in your code, whenever you are using an Auction object and you want to retrieve the associated type (if any), you can use:
$type = $auction->type()->get();
Which will return the instance of Type, and you will be able to retrieve the property name like so:
$type->name
I hope this helps! Let me know if you have any more questions!
Your second edit makes a lot of sense. Your method name is typ but that's also the name of the column. So when you use $auktion->typ() it's actually loading the relationship. When you use $auktion->typ it's grabbing the value of that column.
You need to either continue working this way using the parenthesis to load the relation and no parenthesis to grab the value of the column, or you can change the name of the column to something better such as typ_id which is ultimately what Laravel expects it to be and should save you from more similar headaches down the road.
You can try this in your Auktion model
$thetyp = App\Typ::find(1);
$auktion->typ->save($thetyp);
Now fetch
$auktion->typ->name

How to link data from one table to another using Laravel 4?

I have a customers migration table
Schema::create('customers', function(Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('address');
$table->string('phone');
$table->string('email');
});
and a tripsheet migration table which goes like this
Schema::create('tripsheets', function(Blueprint $table) {
$table->increments('id');
$table->integer('tripsheet_num');
$table->integer('customer_id');
$table->string('date');
$table->string('customer_name');
$table->string('customer_address');
$table->string('customer_phone');
$table->string('rep_address');
$table->string('rep_phone');
});
I have also created a customer eloquent,
class Customer extends Eloquent {
public $timestamps = true;
public $table = 'customers';
protected $fillable = ['name', 'address', 'phone', 'email'];
public function tripsheets(){
return $this->belongsTo('Tripsheet', 'name', 'address', 'phone');
}
}
and a tripsheet model,
class Tripsheet extends Eloquent {
public $timestamps = true;
public $table = 'tripsheets';
protected $fillable = [];
public function customer(){
return $this->hasMany('Customer', 'name', 'address', 'phone');
}
}
and my routes.php goes like this,
Route::get('/', function()
{
return View::make('hello');
});
Route::controller('/customers', 'CustomerController');
Route::controller('/tripsheets', 'TripsheetController');
I would like to link the customer_name, customer_address, customer_phone from the tripsheet table to the name, address, phone of the customer table. I also want to know how to route them and fetch them as a json data to be used by angular JS to display the result.
now should i create a third table to link these two? Or should i call it with Customer::with('tripsheets')->all();in the routes/controller?
I also want to know how to route them and fetch them as a json data to be used by angular JS to display the result.?
I overlooked your code and after user315.. answer I see the problem. The belongsTo and hasMany has wrong arguments.
You need to change your code to the following to make it work:
class Customer extends Eloquent {
public function tripsheets(){
return $this->belongsTo('Tripsheet', 'tripsheet_num');
}
}
class Tripsheet extends Eloquent {
public function customer(){
return $this->hasMany('Customer', 'tripsheet_num');
}
}
The problem is that you have the field tripsheet_num in the table tripsheets. Laravel tries to find a field called tripsheet_id inside the tripsheets table when you use the belongsTo(Tripsheet) on Customer. In your case this key field is named different and is not found, and so the relation is not set.
Same goes for hasMany() only then it looks in the other table for the key field.
See the relation documentation for more info: One-to-one relation & hasMany
You only need the first argument in your belongsTo and hasMany method. The others are likely the reason why it's not working. They are meant for telling Eloquent what the foreign key is, and if you are specifying the foreign key as name, then it's obviously not going to work right.
Since you have proper naming conventions, Eloquent can accurately guess what they should be and you shouldn't need them.

Categories