Laravel relationship returning null - php

I'm trying to fetch database data through a model relationship in Laravel.
I've set up one model, like this:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class Userskeywords extends Eloquent {
public function relatedKeywords()
{
return $this->hasOne('Keywords', 'id', 'keywordId');
}
}
?>
And the other model is just a normal model. In the database they look like this:
Keywords
UsersKeywords
However, when I run UsersKeywords::with('relatedKeywords')->get() it returns NULLfor related_keywords. This happens when the following code is executed. What am I doing wrong?
$keywords = Userskeywords::where('user', '=', $id)->get();
$keywords->load('relatedKeywords');
return Response::json($keywords);

Your relation is called relatedKeywords so you need to access related object with
$object->relatedKeywords
instead of
$object->related_keywords

Related

Specify DB table in laravel query

Im new to laravel, i am trying to query a specific table in my DB. I only have 1 data table and the standard user auth tables. I am getting a error: BadMethodCallException
Call to undefined method App\Figures::table().
Model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Figures extends Model
{
}
controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Figures;
class figuresController extends Controller
public function figurespag2() {
$dummyDetails = Figures::table('figures')->where('name', 'batman');
return view ( 'pagination2.index' )->withUsers($dummyDetails);
}
route
Route::get ( '/pagination2', 'figuresController#figurespag2' );
I know it's going to be something obvious, but I am new to this.
this is wrong
$dummyDetails = Figures::table('figures')->where('name', 'batman');
Method 1---------- laravel eloquent
Model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Figures extends Model
{
protected $table = 'figures';
}
Controller
$dummyDetails = Figures::where('name', 'batman')->get();
and
Method 2 ---------- laravel Query Builder
$dummyDetails = \DB::table('figures')->where('name', 'batman')->get();
Use this you not need to define table name
public function figurespag2() {
$dummyDetails = Figures::where('name', 'batman')->get();
return view ( 'pagination2.index' )->withUsers($dummyDetails);
}
First you may need to know laravel model rules.
If you create a table name like "figures" (plural) you need to create its model by Figure (singular).
if you create a table other then this rule then you have to mentioned table name in model like this.
protected $table = "table_name";
you can access table with where condition in controller like this.
public function figurespag2() {
$dummyDetails = Figure::where('name', 'batman')->get();
return view ( 'pagination2.index' )->withUsers($dummyDetails);
}
Hope this may help you.

Eloquent eager loading does not return related model data

In my Laravel project I have two Eloquent Models Set and Card, they have one to many relationship between them. Set has many Cards and Cards belong to Set.
I'm trying to pull the data using Eloquent Eager Loading using the with() function. But for some reason the cards array inside sets is returning as blank [].
Set.php
<?php
namespace App;
use App\Card;
use Illuminate\Database\Eloquent\Model;
class Set extends Model
{
protected $table = "sets";
public function cards() {
return $this->hasMany('App\Card');
}
}
Card.php
<?php
namespace App;
use App\Set;
use Illuminate\Database\Eloquent\Model;
class Card extends Model
{
protected $table = "cards";
public function sets() {
return $this->belongsTo('App\Set');
}
}
Controller code
$sets = Set::with([
'cards' => function($query){
$query->select('name', 'description');
},
])->get();
return $sets;
name and description are the fields that I have in Cards table except of the primary key and foreign key.
It returns with "cards": [] in my JSON array of sets.
I have tried using below code in controller,
$sets = Set::with('cards.*')->get();
return $sets;
Did not work.
Tried adding the foreign key (set_id which is in the Cards table) in the hasMany method in my Set model that creates relationship with Cards table. But of no result.
To be mentioned, when I tried pulling the data from Cards table separately from my CardController, it returned all Cards data.
Some clue would mean great help. Thank you for your time.
Try this code in your controller,
$sets = Set::with('cards')->get();
return $sets;
Let me know if it works
Try something like this:
public function sets() {
return $this->belongsTo('App\Set','id','id_set');
}
the second parameter "id" is the id of table Set, and the third parameter "id_set" is the foreing key in the Card Table.

Laravel Eloquent one to many relationship not working

I'm obviously missing something. I thought I was comfortable around laravel relationships...
I've 2 tables, named ratings and ratingdetails. The models are named Rating & Ratingdetail:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Rating extends Model
{
public function ratingdetails()
{
return $this->hasMany('App\Ratingdetail');
}
public function campaigns()
{
return $this->hasMany('App\Campaign');
}
}
and
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;
class Ratingdetail extends Model
{
use HasTranslations;
public $translatable = ['value'];
public function rating()
{
return $this->belongsTo('App\Rating');
}
}
When I try to access to my Rating model it works fine, but I can't access the relationships; the output is the following, despite there should be 4 Ratingdetails rows...:
{"id":1,"description":"fontawesome","created_at":null,"updated_at":null,"deleted_at":null}
Thank you all for your time !
$rating = Rating::find($request->rating_id);
return $rating->toJson();
In the above line of code, you're never accessing the ratingdetails relationship. They are not included by default, and need to be loaded before being available:
$rating = Rating::with(["ratingdetails"])->find($request->rating_id);
return $rating->toJson();
Including it via with() will "Eager load" the relationship and expose it to be accessed via
console.log(rating.ratingdetails);
// Will contain an array of 4 objects
Before converting to json, you'd be able to access $rating->ratingdetails, but once converted, you lose access unless you have previously loaded the relationship.
Actually I can't answer for this question without having the Models' $fillable attributes, or without DB Tables structures. But I think your tables have following columns:
"raitings" -> "id", "description", "created_at", "updated_at", "deleted_at"
"raitingdetails" -> "id", "raiting_id", "value", ...
In normal way, you need to create OneToMany relation for that 2 tables with foreign key. So in your "raitingdetails" migration you need to have something like this:
$table->unsignedBigInteger('raiting_id')->nullable();
$table->foreign('raiting_id')->references('id')->on('raitings')->onUpdate('cascade')->onDelete('cascade');
Your models are correct, but it not just cool now.. You can improve them by adding $fillable columns and FKs of relations (Note: if you're using traditional foreign key concept, like "partents.id"->"childs.partent_id", then you can leave this part too).
For getting all Rating details of 1 Rating, you can do this:
$rating = Rating::find($rating_id);
$rating_details_of_one = $rating->ratingdetails()->get()->toJson();
If you want to have Rating Details for all actions, you can add Accessor in your Rating model and attach that to $appends like this:
protected $appends = [ 'rating_details' ]; public function
public function getRatingDetailsAttribute() {
return $this->ratingdetails;
}
And in logic parts you can access like this:
$ratings = Rating::find($rating_id); // this will get with their "ratingdetails" relation
Or you can attach accessor on the fly without protected $appends and getRatingDetailsAttribute() function like this:
$rating = Rating::find($rating_id);
$rating_details_of_one = $rating->setAppends([ 'rating_details' ])->get()->toJSON();
If you want to have some Ratings with their details, you can use something like this:
$rating_details_of_many = Rating::where('description', 'fontawesome')->with('ratingdetails')->get()->toJson();

Alternatives to writing joins with foreign keys in eloquent?

I'm using laravel-eloquent and want to return a collection that joins several tables. For now, I do this using the query builder join method, but I would like to stay within eloquent. I mean, I already defined all my relationships, why should I write joins with foreign keys all the time?
For example, if I have defined my models like this:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function comments()
{
return $this->hasMany('App\Comments');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
and want to return all the comments with the user names, for now I would write this:
DB::table('users')->select('users.name', 'comments.body')
->join('comments', 'users.id', '=', 'user_id')
->get();
I have tried writing
$users = new 'App\User';
$users->with('comments')
->select('name', 'comments.body');
but it didn't work. Do I need to define a new collection? I will end up with many, many collections if I do that...
Try:
$result = null;
$users = new 'App\User';
$records = $users->with('comments')->get();
if ($records->isNotEmpty()){
$result = $records->map(function($val,$key){
return ["name"=>$val->name, "comments" => $val->comments()->get(['body']);
})->values()->all();
}
dd($result);
I have not tested the codes yet. Please check and let me know if it works for you?

Laravel 5 mutators only work when I create a record and not when I update a record

Hi I have created a mutator to only store digits on my phone numbers. Here is my code in my Profile Model.
public function setPhoneAttribute($phone)
{
$this->attributes['phone'] = preg_replace("/[^0-9]/","",$phone);
}
This works when I create a new record, but if I update the record it does not work. My question is how do I execute the Mutator on both create and update?
Here is how I update and create in my controller:
namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Requests\ProfileRequest;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Auth;
use App\Profile;
class ProfileController extends Controller {
public function create(ProfileRequest $request)
{
// Check if the user does not have a profile yet
if(!Auth::user()->profile()->first()){
// Save to database
$saveToDatabase = Auth::user()->profile()->create($request->all());
return $saveToDatabase;
}
}
public function update(Profile $profile, ProfileRequest $request)
{
// Save to database
$saveToDatabase = Auth::user()->profile()->update($request->all());
return $saveToDatabase;
}
}
Here's what's happening:
Auth::user()->profile()->create($request->all()) calls the create method on your relationship (HasOneOrMany). This method then creates a new instance of the related model. This is important because obviously attribute mutators are only used when the record is created through the model.
However the relationship object doesn't have any update method. (It also wouldn't make sense to have one...). So what's happening instead is, when you do Auth::user()->profile()->update($request->all()). The update call get's proxied off to a query builder instance (that matches the relationship). This results in something like this being executed:
UPDATE profiles SET foo = 'bar' WHERE [relationship conditions]
It doesn't use the model at all. Therefore the mutator doesn't work.
Instead you have to call the update method on the actual related model. You can access it by just calling the relation as a property like this:
$saveToDatabase = Auth::user()->profile->update($request->all());
// ^^
// no parentheses
If the Profile model is injected correctly you actually might also just use that though:
public function update(Profile $profile, ProfileRequest $request)
{
// Save to database
$saveToDatabase = $profile->update($request->all());
return $saveToDatabase;
}
Using this code instead of your code
$saveToDatabase = Auth::user()->profile->update($request->all());

Categories