Eloquent, Delete not working, Laravel 5 - php

i'm working on a web app using eloquent and laravel 5. The problem is that i'm trying to delete a row of a table called "Ponderacion" but when i send the ajax delete request, the server stops (it stops the execution of the routed function but the server keeps running) at the line where the delete is, without throwing any errors.
Here is the Model of Ponderacion:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Ponderacion extends Model{
protected $table = 'Ponderacion';
protected $fillable = array('ponderacionidearea', 'ConfiguracionDeExamenifconf', 'peso');
public $timestamps = false;
}
Here is the function in the Controller:
public function deleteConfig(Request $request){
error_log('deleting');
$s_area = Area::where('nombre', '=', $request->input('s_area'))->first();
error_log(count($s_area->Configuracion->first()->Ponderacion));
//DB::statement('delete from Ponderacion where idponderacion = 22');
foreach ($s_area->Configuracion->first()->Ponderacion as $ponderacion){
error_log($ponderacion->peso);
try{
$ponderacion->delete();
}catch(Exception $e){
error_log('failure');
}
}
//$s_area->Configuracion->first()->Ponderacion->delete();
error_log('succesfully deleted');
$s_area->Configuracion->first()->delete();
}
I can succesfully print the property "peso" of ponderacion but i'm unable to delete it. Ponderacion has Foreign Keys to other table but no other table has a reference to Ponderacion. I'm able to delete a row of Ponderacion with DB::statement but that is not secure.Succesfully deleted never shows on console.
Thanks in advance.

For AJAX testing, I always prefer to directly test via a GET request first where possible and then layer on the AJAX POST once I know the underlying code works.
In this case, the server is likely throwing a Fatal Error, which will then return a 500 error for an AJAX request and no further information. There is a good SO question that deals with catching Fatal Errors.
I would check your includes for your class. In Laravel 5, the default namespace is not the global namespace for Controllers. You'll need to add a \ before Exception or add use Exception to the top of your class file.
Two tips as well:
Use SoftDeletes on your model. It's better to track and audit your database records if you never really remove a row. DB storage space is really cheap and Laravel will automatically skip the deleted rows when querying.
Use an IDE for development. A lot of these errors can be caught before run-time by a good compiler.

Related

Axios request returns error 500 (laravel, axios & vuejs)

My axios request (combined with Laravel) gives me a 500 error in the web console when I try to save a new question (= Frage):
"Error: Request failed with status code 500"
VueJS-method save():
save: function(){
axios.post('/api/save-frage', this.Frage) //passes the object this.Frage
.then(res => {
// nothing here
});
}
api.php:
Route::post('/save-frage','FragenController#store');
FragenController.php (Controller):
public function store(Request $request)
{
// validation coming soon :)
$frage = new Frage;
$frage->Frage = request('Fragentext');
$frage->save(); //if I comment this out, there's no error 500 :)
}
Frage.php (Model):
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
class Frage extends Model
{
protected $table = 'fragen';
protected $fillable = ['Frage']; // only field to fill is called "Frage"
}
I thought maybe the route was wrong (api.php), but if I change this, I then get a 404 error, so I guess this is correct, since otherwise there would have always been a 404 error.
Then I checked the model if maybe the table or fields were protected but this looks good to me.
What am I doing wrong here?
Thanks guys, by looking in the XHR tab, as well as in laravel.log I saw the issue:
I reused an older table ("Frage") that
didn't have the necessary "created_at" and "updated_at" columns.
has lots of other columns beside "Frage" without a default value, that needed input as well.
My solution:
add the missing two columns
send the other column values in the this.Frage also.

Laravel Model not retrieving data

Im using laravel to pull some log information from a database, but all of a sudden its stopped working, as in its not retrieving data and not returning anything. Im using vuejs to retrieve the data without page refresh, theres no problem on the front end because data can still be retrieved also in the chrome debug console its displaying as a 500 error.
Furthermore what i find weird is it works locally but not in production.
Example code of what works and what doesn't
<?php
namespace App\Http\Controllers;
use App\Log;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class LogController extends Controller
{
public function getLogData()
{
//This is the original code & it doesn't work in production!
//$data = Log::orderBy('id', 'DESC')->select('action', 'object_id', 'ip_address', 'user', 'time', 'date')->get();
//This works! But only retrieves 1 row of information
$data = Log::where('id', 1)->get();
$data = str_replace('*', "<b>", $data);
$data = str_replace('^', "</b>", $data);
return $data;
}
}
and heres the logs model, which shouldnt really affect anything but entering data into the database really but just incase anyone needs this information.
namespace App;
use Illuminate\Database\Eloquent\Model;
class Log extends Model
{
protected $fillable = ['action', 'object_id', 'object_type', 'ip_address', 'user', 'time', 'date'];
}
Any help i get will be appreciated.
The answer to this question can be found here in detail: Limit on amount of rows retrieved MySql, Laravel
In short my Mysql query was pulling back more than my set limit of data due the the growing daily data of my logs table. Increased the limit and everything was working as usual.
I would check the php5 error file, check your php.ini for the location of the error file on the production machine. 500s missing in the logs endup in the php error file log sometimes. There can be a memory leak e.g a string too long for php memory to process it since its returing a log entry which can sometimes be long.
Also, Can you make the select statement as the first thing that you pass to the model like this (won't solve the issue at hand but its best practice to do so )
Log::select('action', 'object_id', 'ip_address', 'user', 'time', 'date')
->orderBy('id', 'DESC')
->get();

Dynamically add columns in an existing table on the fly in CakePHP 3

I want to add column in my existing table in CakePHP 3.
My ContactsTable.php file code:
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use Migrations\AbstractMigration;
class ContactsTable extends Table
{
public function initialize(array $config)
{
$this->addBehavior('Timestamp');
$table = $this->table('contacts');
$table->addColumn('price', 'decimal')->update();
}
}
I have tried as described in CakePHP 3 documentation but I got this error:
Call to a member function addColumn() on a non-object
How do I add columns on-the-fly via the controller?
Code:
<?php
namespace App\Controller;
use Cake\Core\Configure;
use Cake\Network\Exception\NotFoundException;
use Cake\View\Exception\MissingTemplateException;
use Cake\ORM\TableRegistry;
use Cake\Database\Schema\Table;
use Cake\Datasource\ConnectionManager;
use \Migrations\AbstractMigration as AbstractMigration;
use \Phinx\Db\Adapter\MysqlAdapter as MysqlAdapter;
class PagesController extends AppController
{
public function display()
{
$connectionArray = ConnectionManager::get('default')->config();
$connectionArray['pass'] = $connectionArray['password'];
$connectionArray['user'] = $connectionArray['username'];
$connectionArray['name'] = $connectionArray['database'];
$migrationObject = new AbstractMigration(mt_rand());
$migrationObject->setAdapter(new MysqlAdapter($connectionArray));
$tree = $migrationObject->table('tests');
$tree->addColumn('something', 'text')
->update();
}
}
After few hours of Hacking, finally found a way to do it on-the-fly.
Tested in default cakephp 3 (latest - as of today - 2nd June '16)
If you are using a different database adapter, change it to that adapater from MysqlAdapter.
Note to the users:
This is an ugly hack and should be used ONLY if you do not work in
an organization where each migration commit requires peer reference.
mt_rand() must NEVER be used as a version number hack.
There is no canonical way of doing it via the controllers. Update in a datasource MUST always be done modified via migrations - using a proper structure.
Refer to Running Migrations in a non-shell environment and try to create a migrations logs under /config/migrations, that would be more rule-specific-on-the-fly and you will also have logs for peers to review.
Migration plugin also support Running Migrations in a non-shell environment.
Since the release of version 1.2 of the migrations plugin, you can run migrations from a non-shell environment, directly from an app, by using the new Migrations class. This can be handy in case you are developing a plugin installer for a CMS for instance. The Migrations class allows you to run the following commands from the migrations shell: migrate, rollback, markMigrated, status and seed.
Each of these commands has a method defined in the Migrations class.
You can prepare some custom handler which will accept column data from user side and run migration. In this case it could be some form with name and type inputs. Migration will be applied to DB after form with data will be submitted.
Here is how to use it:
use Migrations\Migrations;
$migrations = new Migrations();
// Will return an array of all migrations and their status
$status = $migrations->status();
// Will return true if success. If an error occurred, an exception will be thrown
$migrate = $migrations->migrate();
// Will return true if success. If an error occurred, an exception will be thrown
$rollback = $migrations->rollback();
// Will return true if success. If an error occurred, an exception will be thrown
$markMigrated = $migrations->markMigrated(20150804222900);
// Will return true if success. If an error occurred, an exception will be thrown
$seeded = $migrations->seed();
If you want add new column to product table e.g 'price' and price is a 'decimal' you should go to your project and write this in console:
bin/cake bake migration AddPriceToProducts price:decimal
You can see a new file e.g. Config/Migrations/20160501190410_AddPriceToProducts.php
<?php
use Migrations\AbstractMigration;
class AddPriceToProducts extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-change-method
* #return void
*/
public function change()
{
$table = $this->table('products');
$table->addColumn('price', 'decimal', [
'default' => null,
...
'null' => true,
]);
$table->update();
}
}
and later just launch migrations to add this column to data base, write this in console:
bin/cake migrations migrate

How to connect to Heroku connect's table that is created as custom field in salesforce in cake php v3.x

I am trying to connect with Heroku connect table via CakePHP 3. For some reason, I get the following error when I try to connect with a table whom name ends in '__c'
PHP Fatal error: Call to a member function newEntity() on boolean
Previously, I solved fundamental connection problem that I had in CakePHP at
Heroku Connect with Cakephp v3.0.12 form.
So I could connect with one that doesn't have '__c' in its table name. From the error msg, I understand for some reason my cake app failed to connect with the table I want to connect.
In my App/Model/Table/someFieldTable.php, I have
public function initialize(array $config)
{
parent::initialize($config);
$this->table('salesforce.some_field__c');
$this->displayField('name');
$this->primaryKey('id');
}
I also have the following in my tableController.php
$somefield = $this->someField->newEntity();
// variables are assigned to $somefield
if($this->someField->save($someField)){
// error handling here
}
I am still new to CakePHP and Heroku connect. If anybody knows how to connect with these field (table) with postfix '__c' in CakePHP, Please help me.
Using the TableRegistry class is an effective answer, here is the correct method of getting the autowired table in the controller working:
As you've already been informed, your file naming scheme is incorrect, but that's not the full solution to your table name formatting with Heroku. Your entry within $this->table() should not be namespace to a database with a dot, as the database is appending via the current connection (which is most likely the default datasource defined in app.php) you are making queries on. The entire fix would consist of:
// 1. Change the file name to the correct scheme: SomeFieldTable.php
// 2. In order for the controller to autowire the table, you must correctly
// name the controller file as well: SomeFieldController.php
// 3. Change the table name within SomeFieldTable.php to the appropriate
// name: 'some_field_c'
public function initialize(array $config)
{
parent::initialize($config);
$this->table('some_field__c');
$this->displayField('name');
$this->primaryKey('id');
}
// 4. Finally, in the controller, the table is accessed via the camel capsed name
class SomeFieldController extends AppController
{
public function getEndpoint()
{
$result_set = $this->SomeField->find()->all();
$this->set('result_set', $result_set);
}
public function saveEndpoint()
{
$new_some_field = $this->SomeField->newEntity($this->request->data);
if ($this->SomeField->save($new_some_field)) {
$this->set('new_some_field', $new_some_field);
} else {
$this->set('errors', $new_some_field->errors());
}
}
}
Thanks to ndm Cake is sensitive to its class name and letter cases when I use these special classes.
I also solved the problem over the night.
In my controller, I added individual entity classes additionally to table class.
use App\Model\Entity\SomeFields;
use Cake\ORM\TableRegistry;
and When I create data object, I use manually construct these classes instead to use newEntity()
$someFieldTable = TableRegistry::get('BottomSheet');
$someField = new SomeFileds();
Now I can assign variable to data object manually
For instance
$someField->fieldName = data['fieldName'];
In order to save the data, I now have to manually call the save function
$someFieldTable->save($someField)
and ... Voila!
This is my dirty type of solution, I should fix the name of classes and files properly tho.
Thank you again for the help ndm!

Kohana ORM Update not working

I have discovered Kohana just 2 days ago and, after facing a few problems and managing to deal with them, I ran into a quite strange one.
When I try to update an entry in DB, instead of updating the entry ORM just inserts a new row.
Everything is similar to this example http://kohanaframework.org/3.0/guide/orm/examples/simple
My code (controller file):
class Controller_Admin extends Controller {
...
public function action_test($id)
{
$inquiry = ORM::factory('inquiry')->where('Id', '=', $id)->find(); // $inquiry = Model_Inquiry($id) doesn't work, too
$inquiry ->Name = 'Someone';
$inquiry ->save();
}
...
}
Model file:
class Model_Inquiry extends ORM
{
protected $_table_name = 'mytable';
}
Do you have any ideas why it's inserting a new entry instead of updating the old one? I read that it's because the ID is not correctly set, but I tried using a fixed value (->where('Id', '=', 5)) and it didn't work (it still inserted a new row).
Thanks in advance!
Your record isn't loaded in the first place. To check if it's loaded, do:
if ($inquiry->loaded()){...
Also, you can check what query has been run by doing:
echo $inquiry->last_query();
So you can manually check what exactly is being returned to ORM.
The main problem here is that you're using save() instead of being more strict and using create() / update(). If you used update(), ORM would throw an exception complaining about the record not being loaded.
Save is basically a proxy to these methods, relying on the loaded state.
(I assume that you're using Kohana 3.1 since 3.0 ORM doesn't have separate update / create methods at all)

Categories