I followed this tutorial to get Laravel's Eloquent running inside an existing Codeigniter project and everything worked fine until I attemped to use Eloquent's relationships. Here's my offending code:
class Announcement_model extends Eloquent {
protected $table = 'announcements';
public function game() {
$this->load->model('game_model');
return $this->belongsTo('Game_model', 'game_id');
}
}
class Game_model extends Eloquent {
protected $table = 'games';
}
And the controller:
class Api_announcement extends REST_Controller {
...
public function index_get() {
$response = Announcement_model::with('game')->get();
$this->response(array('error'=> false, 'response' => $response), 200);
}
}
I'm running into this error:
<b>Fatal error</b>: Uncaught exception 'LogicException' with message 'Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation' in myproject\vendor\illuminate\database\Eloquent\Model.php:2695
Stack trace:
#0 myproject\vendor\illuminate\database\Eloquent\Model.php(2665): Illuminate\Database\Eloquent\Model->getRelationshipFromMethod('load')
#1 myproject\vendor\illuminate\database\Eloquent\Model.php(2607): Illuminate\Database\Eloquent\Model->getRelationValue('load')
#2 myproject\vendor\illuminate\database\Eloquent\Model.php(3325): Illuminate\Database\Eloquent\Model->getAttribute('load')
#3 myproject\application\models\announcement_model.php(11): Illuminate\Database\Eloquent\Model->__get('load')
#4 myproject\vendor\illuminate\database\Eloquent\Builder.php(477): Announcement_model->game()
#5 [internal function]: Illuminate\Database\Eloquent\Builder->Illuminate\Database\Eloquent\{closure}()
#6 in
<b>myproject\vendor\illuminate\database\Eloquent\Model.php</b> on line
<b>2695</b>
What am I doing wrong? I've looked up and down for a solution but nothing works.
return $this->belongsTo('Game_model', 'game_id')->select(array('name'));
Returns in array, but no Relation. You need this:
return $this->belongsTo('Game_model', 'game_id');
Related
I have a method scoup scopeCalculateMaxPositionSelectedCategory in my Model Category
class Category extends Model
{
use HasFactory;
protected $fillable = [
'parent_id',
'name',
'slug',
'description',
'position',
'quantity_available_offers',
];
public function scopeCalculateMaxPositionSelectedCategory($query, $cat_id = null) {
return $query->where('parent_id', $cat_id)->max('position');
}
}
When i call like that it's work fine:
Category::CalculateMaxPositionSelectedCategory();
But i want do this that way:
$this->categories->CalculateMaxPositionSelectedCategory();
After this are error:
"BadMethodCallException
Method Illuminate\Database\Eloquent\Collection::CalculateMaxPositionSelectedCategory does not exist. "
Show me why I want to do that, because i want to use this in component Livewire:
public $selCategory = '';
public $categories;
public $selPosition;
public function render()
{
$this->categories = Category::all();
$this->selPosition = $this->categories->CalculateMaxPositionSelectedCategory() + 1;
return view('livewire.form-stor-category');
}
It supposes the error is due to all () calling get (). But I have no idea how to solve it.
$this->categories->CalculateMaxPositionSelectedCategory();
^ This line gets the categories as a collection, and then you can't call a query scope on a collection.
Try this:
$this->categories()->CalculateMaxPositionSelectedCategory()->get();
The () after categories will continue building the query but won't run it yet. When you call $this->categories without the () it runs the query straight away and your opportunity to use the scope is gone.
I try to get user id in my app service provider, but I get an error show that ErrorException: Trying to get property of non-object, any idea how on how to get user id?
AppServiceProvider:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Project;
use Log;
use Auth;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
$userid = Auth::user()->id;
Log::info('userid :', [$userid]);
$project = Project::where('user_id',Auth::user()->id)->count();
}
}
Error:
local.ERROR: ErrorException: Trying to get property of non-object in C:\wamp64\www\test\app\Providers\AppServiceProvider.php:20 Stack trace: #0 C:\wamp64\www\test\app\Providers\AppServiceProvider.php(20): Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(8, 'Trying to get p...', 'C:\\wamp64\\www\\f...', 20, Array) #1 [internal function]: App\Providers\AppServiceProvider->boot() #2 C:\wamp64\www\test\vendor\laravel\framework\src\Illuminate\Container\Container.php(507): call_user_func_array(Array, Array) #3 C:\wamp64\www\test\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(734): Illuminate\Container\Container->call(Array) #4 C:\wamp64\www\test\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(717): Illuminate\Foundation\Application->bootProvider(Object(App\Providers\AppServiceProvider)) #5 [internal function]: Illuminate\Foundation\Application->Illuminate\Foundation\{closure}(Object(App\Providers\AppServiceProvider), 19) #6 C:\wamp64\www\test\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(718): array_walk(Array, Object(Closure)) #7 C:\wamp64\www\test\vendor\laravel\framework\src\Illuminate\Foundation\Bootstrap\BootProviders.php(17): Illuminate\Foundation\Application->boot() #8 C:\wamp64\www\test\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(203): Illuminate\Foundation\Bootstrap\BootProviders->bootstrap(Object(Illuminate\Foundation\Application)) #9 C:\wamp64\www\test\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(222): Illuminate\Foundation\Application->bootstrapWith(Array) #10 C:\wamp64\www\test\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(117): Illuminate\Foundation\Http\Kernel->bootstrap() #11 C:\wamp64\www\test\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(87): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request)) #12 C:\wamp64
Use View::composer('*',) to use Auth in all view .
use Illuminate\Support\Facades\View;
.........
public function boot()
{
View::composer('*', function($view)
{
if (Auth::check()){
$project = Project::where('user_id',Auth::id() )->count();
}
});
You can understand it as after authentication before view render you need to check between these not before.
Auth will always try to get the id even user is logged in or not. In case user is not logged in then it will give you non-object error because nothing is there to get via User model object.
public function boot()
{
if (Auth::check()) {
$userid = Auth::user()->id;
Log::info('userid :', [$userid]);
$project = Project::where('user_id',Auth::user()->id)->count();
}
}
Good luck.
In the boot() method of your service providers, you should only bootstrap your application and not perform any action regarding looking up or outputting data. You can do this in the register() method of your providers, if it is really necessary to do it in a service provider. A better place would probably be a controller or a command anyway, though.
Using Auth::user() directly is dangerous as well, because there might be no user authenticated in your app. You can instead perform a if(Auth::check()) { ... } before accessing the user with Auth::user(), or, which in your case would be sufficient, you can access the user id with Auth::id(). It will also return null if no user is available, i.e. Auth::check() === false.
I'm new to Laravel.
I have two tables related to each other.
I want to set null to the related table record when the other related table record is soft deleted.
I know how to soft delete when the other related table record, but how can I set null instead of soft-delete?
Product Model (Edited)
class Product extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
public $table = "products";
public function projects()
{
return $this->hasMany("App\Model\Project");
}
public static function boot(){
parent::boot();
static::deleted(function($product)
{
//set null
$product->projects()->setNull();
});
}
}
Project Model(Edited)
<?php
class Project extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
public function product()
{
return $this->belongsTo("App\Model\Product");
}
public function setNull()
{
$this->product_id = NULL;
$this->save();
}
}
Table Schema
Schema::create('projects', function (Blueprint $table) {
$table->increments('id');
$table->string('project_name')->unique("project_name");
$table->integer('project_value')->unsigned();
$table->integer('product_id')->unsigned()->nullable();
$table->foreign('product_id')->references('id')->on('products')->onDelete("set null");
$table->timestamps();
$table->softDeletes();
$table->engine = 'InnoDB';
});
note
one project belongs to one product. It seems a bit weird but it's ok.
Error Message
When I delete a product record, I got the following error.
[2017-05-13 17:25:28] local.ERROR: BadMethodCallException: Call to undefined method Illuminate\Database\Query\Builder::setNull() in /vagrant/door/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2443
Stack trace:
#0 /vagrant/door/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(1239): Illuminate\Database\Query\Builder->__call('setNull', Array)
#1 [internal function]: Illuminate\Database\Eloquent\Builder->__call('setNull', Array)
#2 /vagrant/door/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/Relation.php(340): call_user_func_array(Array, Array)
#3 /vagrant/door/app/Model/Product.php(44): Illuminate\Database\Eloquent\Relations\Relation->__call('setNull', Array)
#4 /vagrant/door/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(348): App\Model\Product::App\Model\{closure}(Object(App\Model\Product))
#5 /vagrant/door/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(199): Illuminate\Events\Dispatcher->Illuminate\Events\{closure}('eloquent.delete...', Array)
#6 /vagrant/door/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(172): Illuminate\Events\Dispatcher->dispatch('eloquent.delete...', Array, false)
#7 /vagrant/door/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php(148): Illuminate\Events\Dispatcher->fire('eloquent.delete...', Object(App\Model\Product))
#8 /vagrant/door/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(748): Illuminate\Database\Eloquent\Model->fireModelEvent('deleted', false)
#9 /vagrant/door/app/Http/Controllers/ProductController.php(80): Illuminate\Database\Eloquent\Model->delete()
#10 [internal function]: App\Http\Controllers\ProductController->destroy(Object(App\Http\Requests\ProductRequest), '1')
Check out dissociate() method, this will reset both the foreign key of the relation and the relation on the object.
Basically you want something like this:
static::deleted(function($product)
{
// remove relation
$product->projects()->each(function($project) {
$project->product()->dissociate();
$project->save();
});
});
In your project model define a custom method like,
public function setNull()
{
$this->field_names= NULL;
$this->save();
}
Then in the boot function you call this method like
$product->projects()->setNull();
P. S- sorry I'm on mobile
I'm trying to pass an array of database entries to a view using Eloquent. I'm new to MVC development. The code is as follows:
School.php (model)
class School extends Eloquent
{
protected $table = 'Schools';
public $timestamps = false;
protected $softDelete = false;
public function school()
{
return $this->hasOne('School');
}
}
SchoolController.php (controller)
class SchoolController extends BaseController
{
public $restful = true;
public function getIndex()
{
return View::make('schools')
->with('schools', School::all());
}
}
schools.blade.php (View)
#extends('layouts.schools')
#section('school-search')
<ul>
#foreach($schools as $school)
<li>{{ $school->name }}</li>
#endforeach
</ul>
#stop
However, I'm getting a white screen of death when I load the page. The view works fine when I comment out the "->with('schools', School::all())" part, so I think it has to do with Laravel failing to access the School object. I've googled/stackoverflowed a bit and can't find anyone with a similar problem.
Thanks!
edit: Some relevant info:
I have had this problem before, where it would whitescreen anything I routed to, however I corrected that by changing app/storage permissions. Changing permissions does not seem to help this whitescreen problem.
Laravel seems to be error reporting just fine. When there is something that doesn't make sense in my code, I get an error.
We are in development environment.
edit:
when I run php artisan serve, it gives an error "This php binary is not version 5.4 or greater" Could this be related?
edit:
I've updated to PHP 5.4. Still whitescreening. Here is the latest in my error log.
#0 /var/www/playground/vendor/laravel/framework/src/Illuminate/Foundation/Console/ServeCommand.php(29): Illuminate\Foundation\Console\ServeCommand->checkPhpVersion()
#1 /var/www/playground/vendor/laravel/framework/src/Illuminate/Console/Command.php(108): Illuminate\Foundation\Console\ServeCommand->fire()
#2 /var/www/playground/vendor/symfony/console/Symfony/Component/Console/Command/Command.php(241): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#3 /var/www/playground/vendor/laravel/framework/src/Illuminate/Console/Command.php(96): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#4 /var/www/playground/vendor/symfony/console/Symfony/Component/Console/Application.php(892): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#5 /var/www/playground/vendor/symfony/console/Symfony/Component/Console/Application.php(191): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Foundation\Console\ServeCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#6 /var/www/playground/vendor/symfony/console/Symfony/Component/Console/Application.php(121): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#7 /var/www/playground/artisan(59): Symfony\Component\Console\Application->run()
#8 {main} [] []
The problem is with your School.php's relationship defination.
public function school()
{
return $this->hasOne('School');
}
By this you are telling laravel that this model has a one-to-one / one-to-many relationship with itself and this causes a recursive loop when School::all() is called. Once the loop exceeds the max allowed memory size as set in php.ini, it will return an empty response. Thats why you are getting a blank screen.
This relationship does not seem logical to me but if the schools are hierarchical, you should change the method name school() to something like parent() to avoid confusing laravel. Eg..
public function parent()
{
return $this->hasOne('School', 'parent_id');
}
class School extends Eloquent
{
protected $table = 'Schools';
public $timestamps = false;
protected $softDelete = false;
public function school()
{
return $this->hasOne('School');
}
}
You have a School object which has a one to one relationship with another school object? You also haven't defined the foreign key to the relationship
I think that laravel is just recursively loading school object after school object and then running out of memory before it can build an error. You can test this by commenting out the entire school() function and seeing what happens.
Another question can you access you apache error log?
I am new to Laravel. I Just want to create a self referential model. For example, I want to create a product category in which the field parent_id as same as product category id. How is this possible?
Model Shown below
class Product_category extends Eloquent
{
protected $guarded = array();
public static $rules = array(
'name' => 'required',
'parent_id' => 'required'
);
function product_category()
{
return $this->belongsto('Product_category','parent_id');
}
}
It results Maximum function nesting level of '100' reached, aborting! Error
You can add a relation to the model and set the custom key for the relation field.
Update:
Try this construction
class Post extends Eloquent {
public function parent()
{
return $this->belongsTo('Post', 'parent_id');
}
public function children()
{
return $this->hasMany('Post', 'parent_id');
}
}
Old answer:
class Post extends Eloquent {
function posts(){
return $this->hasMany('Post', 'parent_id');
}
}
Your model is not at fault for producing the "maximum function nesting level of '100' reached" error. It's XDebug's configuration; increase your xdebug.max_nesting_level.
The following is from a 2015 post by #sitesense on laracasts.com:
This is not a bug in Laravel, Symfony or anything else. It only occurs when XDebug is installed.
It happens simply because 100 or more functions are called recursively. This is not a high figure as such and later versions of XDebug (>= 2.3.0) have raised this limit to 256. See here:
http://bugs.xdebug.org/bug_view_page.php?bug_id=00001100
EDIT: In fact the latest Homestead provisioning script already sets the limit to 250. See line 122 here:
https://github.com/laravel/settler/blob/master/scripts/provision.sh#L122
So the addition of xdebug.max_nesting_level = 250 to php.ini should do it.
I've added a little more to the code based on your comments trying to access the parent!
class Person extends \Eloquent {
protected $fillable = [];
var $mom, $kids;
function __construct() {
if($this->dependency_id<>0) {
$this->mother->with('mother');
}
}
public function children() {
$children = $this->hasMany('Person','dependency_id');
foreach($children as $child) {
$child->mom = $this;
}
return $children;
}
public function mother() {
$mother = $this->belongsTo('Person','dependency_id');
if(isset($mother->kids)) {
$mother->kids->merge($mother);
}
return $mother;
}
}
Then you can access the parent from the child with eager loading, see more here: http://neonos.net/laravel-eloquent-model-parentchild-relationship-with-itself/
you can refer self, using $this
class Post extends Eloquent {
function posts(){
return $this->hasMany($this, 'parent_id');
}
}
Take a look at my answer here.
The key is this code below in Model.php
public function children()
{
return $this->hasMany(Structure::class, 'parent_id')->with('children');
}