How to access my model in laravel? - laravel-5

I can't seem to figure out what's wrong with this code. I'm running laravel 5.4.
The error:
https://www.dropbox.com/s/64ioxdf4mv6ps1w/Screenshot%202017-02-28%2020.11.33.png?dl=0
The Controller function:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Thread;
class ThreadController extends Controller
{
public function show($id) {
return Thread::where('id', '=', $id)->messages();
}
}
The Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Thread extends Model
{
public function messages()
{
return $this->hasMany(Message::class)->get();
}
}

I suggest adding your error code instead of linking to image (right now AWS is down, thus I'm unable to view the image).
Regardless, the messages method is defining a relationship and as such, is an instance of the query builder. Rather than chaining the get method there, I suggest a slightly different approach:
In your controller
public function show($id)
{
// Use first() instead of get() since you're returning a
// specific model by its primary key (I assume)
return Thread::where('id', $id)->with('messages')->first();
}
And in your model
public function messages()
{
// This returns a query builder instance, which is what you want.
// It defines the relationship between Thread and Message
return $this->hasMany(Message::class);
}
This will eager load your messages along with your Thread model.
Hope it helps!

Regarding Joel's question in the comments...
User::find(1)->messages->create($request->only('body'));
Is not calling the 'messages function' you mentioned and not returning the relationship. Instead, it is calling the messages property, which is something different.

Related

Overriding routeKeyName to slug not working

Here is my show method in my PostController and when I dd($slug) I get my slug from the database but when I try to search the post associated with that slug I get a 404 | Not Found. I've override my routeKeyName in my model but it seems like it'still fetching using id column since when I replace $slug with a hard coded id of 2 in this line $post = Post::findOrFail($slug); then I get the post from the database. I can't figure out what it is that I'm missing.
public function show($slug)
{
//dd($slug);
$post = Post::findOrFail($slug);
return view('single-blog', compact('post'));
}
My Model Post.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
public function getRouteKeyName()
{
return 'slug';
}
}
Even using a different database field, you're still using route model binding.
From the docs:
Laravel automatically resolves Eloquent models defined in routes or controller actions whose type-hinted variable names match a route segment name.
So your route variable and the field you pass to your controller method need to match, and you need to type hint it:
Route:
Route::get('/posts/{post}', [PostController::class, 'show']);
Controller:
public function show(Post $post) {

withTrashed on hasManyThrough relation

How can withTrashed be applied on a hasManyThrough relation ?
$this->hasManyThrough('App\Message', 'App\Deal')->withTrashed();
returns
Call to undefined method Illuminate\Database\Query\Builder::withTrashed()
when i'm doing:
$messages = Auth::user()->messages()->with('deal')->orderBy('created_at', 'DESC')->get();`
Here is my Deal model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Deal extends Model
{
use SoftDeletes;
/* ... */
protected $dates = ['deleted_at'];
public function user() {
return $this->belongsTo('App\User');
}
public function messages() {
return $this->hasMany('App\Message'); // I've tried to put withTrashed() here, there is no error but it doesn't include soft deleting items.
}
}
To all those coming to this late, there is now a native way of doing this with Laravel.
$this->hasManyThrough('App\Message', 'App\Deal')->withTrashedParents();
This is not well documented but can be found in Illuminate\Database\Eloquent\Relations\HasManyThrough
The error is thrown because you are requesting a messages with deleted ones without using SoftDelete trait in Message model.
After I check the hasManyThrough relation code I found that there is no way to do it in this way, you should play around.
Ex:
get the deals of user with messages instead
$deals = Auth::user()->deals()->withTrashed()->with('messages')->get();
foreach($deals as $deal) {
//Do your logic here and you can access messages of deal with $deal->messages
}

How can i get result from model in laravel 5

Good day, i'm trying to get the result from my model that called with Mainmodel through my controller, my controller is MainController.
Here is my controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use app\Mainmodel;
class MainController extends Controller
{
function index(){
echo "Kok, direct akses sih?";
}
function get_menu(){
$menu = app\Mainmodel::request_menu();
dd($menu);
}
}
Here is my model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Mainmodel extends Model
{
function request_menu(){
$menu = DB::table('menu')
->orderBy('[order]', 'desc')
->get();
return $menu;
}
}
my routes
Route::get('menu','MainController#get_menu');
with my script above i get this
FatalErrorException in MainController.php line 17: Class
'App\Http\Controllers\app\Mainmodel' not found
how can i fix this ? thanks in advance.
Note: I'm bit confuse with laravel. I'm using codeigniter before. And i have a simple question. In laravel for request to database should i use model ? or can i just use my controller for my request to database.
sorry for my bad english.
I would imagine it's because your using app rather than App for the namespace.
Try changing:
app\Mainmodel
To:
App\Mainmodel
Alternatively, you can add a use statement to the top of the class and then just reference the class i.e.:
use App\Mainmodel;
Then you can just do something like:
Mainmodel::request_menu();
The way you're currently using you models is not the way Eloquent should be used. As I mentioned in my comment you should create a model for each table in your database (or at least for the majority of use cases).
To do this run:
php artisan make:model Menu
Then in the newly created Menu model add:
protected $table = 'menu';
This is because Laravel's default naming convention is singular for the class name and plural for the table name. Since your table name is menu and not menus you just need to tell Laravel to use a different table name.
Then your controller would look something like:
<?php
namespace App\Http\Controllers;
use App\Menu;
class MainController extends Controller
{
public function index()
{
echo "Kok, direct akses sih?";
}
public function get_menu()
{
$menu = Menu::orderBy('order', 'desc')->get();
dd($menu);
}
}
Hope this helps!
You can solve it by different solution. The solution is you don't have to call request_menu(); you can get it in your controller.
MainController
use use Illuminate\Support\Facades\DB;
public function get_menu(){
$menu = DB::table('menu')
->orderBy('Your_Field_Name', 'DESC')
->get();
dd($menu);
}

Unable to maintain one to many relationship in Eloquent using laravel 5.3

I am using laravel eloquent model so there are three tables tempsocials, tempusers and tempdevices. so one user can have multiple devices and multiple social acounts.
I created a models for three of above table and trying to maintain relationship in between like following
This is my Tempuser model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tempuser extends Model
{
public function tempsocials(){
return $this->hasMany('App\Tempsocial');
}
public function tempdevices(){
return $this->hasMany('App\Tempdevice');
}
}
This is my Tempdevice model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tempdevice extends Model
{
public function tempusers(){
return $this->belongsTo('App\Tempuser');
}
}
And this one is last Tempsocial model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tempsocial extends Model
{
public function tempusers(){
return $this->belongsTo('App\Tempuser');
}
}
Now this is my controller where i want to retrive all the devices and social accounts of particular user
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Collection;
use App\Http\Requests;
use App\tempLogin;
use App\Tempdevice;
use App\Tempuser;
use App\Tempsocial;
class loginController extends Controller
{
public function check_credentials(Request $request){
$count=0;
if($request->header('content-type')=='application/json'){
$temp=new Tempuser;
$devices = $temp->tempdevices();
return $devices;
}
}
}
But i got following error:
Object of class Illuminate\Database\Eloquent\Relations\HasMany could
not be converted to string
You're making a new Tempuser(), it has no id, so your relation returns nothing as expected, you will need to pass an id to the method and with that id you could do something like:
Tempuser::find($id);
This will then return an actual model instead of creating a new one.
Also because when you call ->tempdevices() as a function it will return a query builder, instead when you do ->tempdevices it will return a collection, change it like this:
$devices = $temp->tempdevices;
Also, if you expect a json response (if thats not the case you can ignore this part), it might be better to also state it in your return by doing:
return response()->json($devices);

laravel model relation not working

I have created a laravel api for my application.I have used Pingpong module package for different modules.I am having hard time establishing many-to-many relation.I have 3 tables:roles,groups,group_roles.And my models are:
Group.php
namespace Modules\User\Entities;
use Illuminate\Database\Eloquent\Model;
class Group extends Model {
protected $fillable = [];
protected $table='groups';
public static function roles(){
return $this->belongsToMany('Modules\User\Entities\Role','group_roles','group_id','role_id');
}
}
Role.php
namespace Modules\User\Entities;
use Illuminate\Database\Eloquent\Model;
class Role extends Model {
protected $fillable = [];
protected $table='roles';
public function groups(){
return $this->belongsToMany('Modules\User\Entities\Group','group_roles','group_id','role_id');
}
}
And my controller
namespace Modules\User\Http\Controllers;
use Pingpong\Modules\Routing\Controller;
use Modules\User\Entities\Group;
use Modules\User\Entities\Role;
use Illuminate\Http\Request;
use App\Login;
use Input;
use Validator;
use Hash;
use Response;
class UserController extends Controller {
public function getGroupById(Request $request){
$groups=Group::with('roles')->get();
return Response::json ([
'status'=>'ok',
'group'=>$groups
],200);
}
}
The problem is I am not able to establish the relation between the models and the getGroupById returns 500 internal error response.$group=Group::all(); $group=Group::find($request['id']); returns fine but it is not returning related roles.
Similar structure and codes work fine on app without the use pingpong.
Your relationships are currently like this:
// not sure why this is static?
public static function roles(){
return $this->belongsToMany('Modules\User\Entities\Role', 'group_roles', 'group_id', 'role_id');
}
public function groups(){
return $this->belongsToMany('Modules\User\Entities\Group', 'group_roles', 'group_id', 'role_id');
}
Please note from the docs, regarding the belongsToMany method:
The third argument is the foreign key name of the model on which you are defining the relationship, while the fourth argument is the foreign key name of the model that you are joining to...
So with this in mind I think your relationships may be incorrect due to using the wrong arguments on your belongsToMany method calls. I think it should be like this:
public function roles(){
return $this->belongsToMany('Modules\User\Entities\Role', 'group_roles', 'group_id', 'role_id');
}
public function groups(){
return $this->belongsToMany('Modules\User\Entities\Group', 'group_roles', 'role_id', 'group_id');
}
Also if you have intermediate table columns you'd need to declare those on the belongsToMany call.
Hope that helps!
Edit
Firstly, you said getGroupById returns 500 internal error response. Have you tried checking what the actual error is!? 500 internal error doesn't provide much info, I'm sure you'd get to the bottom of things a lot faster if you found out the exact issue through laravel's usual error response page.
I assume you're doing this through an ajax request so you could use the network tab if you're using chrome then click on the 500 request to see the error laravel returns or you can use something like postman and hit the url through that.
If I wanted to quickly check the functionality of the models relationship methods, I'd do the following:
After setting up some data for a group and relationship, could you try running this in tinker or a route for testing/debugging.
$g = Group::first(); // get the first group, or you could use find($id) if you had a specific group in mind
// if you're in tinker
$g->roles; // show the roles
// if you're running on a route
dd($g->roles); // show the roles
While haakym's answer is very detailed, but you can also try changing your mapping table name to convention based 'group_role' instead of 'group_roles'. With this method you will have to supply only one argument to belongsToMany call.
Note that in general it should not matter if the other arguments are correct, but its just another step to debug!

Resources