Database_Exception [ 1146 ]: Table 'kohana.userdetailses' doesn't exist - php

This is my Controller
userdetails.php
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Userdetails extends Controller {
public function action_index() {
$view = new View('userdetails/index');
$this->response->body($view);
}
public function action_add() {
$userdetails = new Model_Userdetails();
$view = new View('userdetails/adddetails');
$view->set("userdetails", $userdetails);
$this->response->body($view);
}
model is
userdetails.php
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Userdetails extends ORM {
}
userinfo.sql
CREATE TABLE `kohana`.`userinfo` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(100) DEFAULT NULL,
`last_name` varchar(100) DEFAULT NULL,
`email` varchar(100) DEFAULT NULL,
`description` text,
PRIMARY KEY (`id`)
);
I am newly learning php and kohana.I am using kohana 3.2 version.I am following this tutorial to create,edit,update and delete data in database.I tried with above code,i am getting this error
"Database_Exception [ 1146 ]: Table 'kohana.userdetailses' doesn't exist [ SHOW FULL COLUMNS FROM `userdetailses` ]"
need some help to solve this.

Kohana guesses the table name if $_table_name is not set. It pluralizes the model name as most of the time a model describes a single object, and the table describes a lot of them.
EDIT:
I saw you actually named your table userinfo and the model userdetails. If that is what you want:
class Model_Userdetails {
protected $_table_name = 'userinfo';
........
}
Or alternatively rename the model to Model_Userinfo, or the table to userdetails and:
--- END EDIT ---
In your case it would seem most appropiate to:
class Model_Userdetails {
protected $_table_name = 'userdetails';
........
}
Offcourse, you could alternatively rename your class to Model_Userdetail so that the table name will be guessed as userdetails
UPDATE:
Even though Kohana should guess these as well (i.e. SHOW FULL COLUMNS FOR table or sth), this might resolve the property not found error as discussed below in the comments.
protected $_table_columns = array(
'id' => array('type' => 'int'),
'firstname' => array('type' => 'string'),
....... // repeat for all columns
);
Update:
There is a typo in your PHP code: deScription. Anyway, it is a good habit to define the table columns as this will save you an extra query every time a model is initialized for the first time. Along with some validation stuff which can take parameters from the array (e.g. the description of type TEXT is more or less not restricted in length, but you might want to limit it to say 2000 characters)

Related

Can I get the primary key inside the facadesdb insert for direct use - Laravel 8

I am learning Laravel 8 and came across this problem. So, I made a controller class with FacadesDB Insert function. This is my code :
public function aksimenulis_laporan(Request $request){
$filefoto = $request->foto;
DB::table('pengaduan')->insert([
'tgl_pengaduan' => date('Y-m-d'),
'nik' => $_POST['nik'],
'isi_laporan' => $_POST['isi_laporan'],
'foto' => $filefoto->getClientOriginalName(),
'status' => '0',
]);
// isi dengan nama folder tempat kemana file diupload
$tujuan_upload = storage_path();
// upload file
$filefoto->move($tujuan_upload,$filefoto->getClientOriginalName());
return redirect('');
}
https://i.stack.imgur.com/VTJyS.png
This is my database table structure.
And I am trying to insert 'foto' with value of 'id_pengaduan' or the primary key, like using this code. Which will be PrimaryKey_OriginalFileName
'foto' => $filefoto-> 'id_pengaduan'.'_'.getClientOriginalName(),
But the problem I didn't have the value yet. Is there a way that I can value 'foto' with the primary key of the table?
you can use the insertGetId method to insert a record and then retrieve the ID:
$pengaduan_id= DB::table('pengaduan')->insertGetId([
'tgl_pengaduan' => date('Y-m-d'),
'nik' => $_POST['nik'],
'isi_laporan' => $_POST['isi_laporan'],
'status' => '0',
]);
DB::table('pengaduan')->where('id',$pengaduan_id)->update(['foto'=>$filefoto->getClientOriginalName()]);
you can not get the id before the insertion operation is done.
you also should do it in transaction, but for now, I will keep it this way.
You cannot (and shouldn't) insert a row and define its primary key. That's kind of the whole purpose of a primary key. You let SQL manage its identifiers, this is good incase of an error, so there are no duplicates in the primary key.
I'll go into eloquent since you're starting new in Laravel, this will make your life easier with DB operations.
First you'd need to make a new model for your table. You can do this using the console command:
php artisan make:model ModelName
Afterwards, navigate to your Models directory (app/Models/) and you'll find the new model ModelName.php
In there, you'd need to specify the table name and the primary key. You can do that with the these two lines:
protected $table = 'pengaduan';
protected $guarded = ['id_pengaduan'];
Your model should now look something like
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ModelName extends Model
{
use HasFactory;
protected $table = 'pengaduan';
protected $guarded = ['id_pengaduan'];
}
Save, and you might need to clear your cache. Do this by running php artisan optimize in the console.
After you are done inserting the data into a new row, you can get the primary key that was assigned to the row like this:
//using eloquent
use App\Models\ModelName;
//insert data
$insertRow = new Pengaduan;
$insertRow->tgl_pengaduan = date('Y-m-d');
$insertRow->nik = $_POST['nik'];
$insertRow->isi_laporan= $_POST['isi_laporan'];
$insertRow->foto = $filefoto->getClientOriginalName();
$insertRow->status = 0;
$insertRow->save();
//get key here
$rowId = $insertRow->pengaduan_id;
If you want to use the DB::table('table')->insert method, see OMR's answer.
If you really want to define the primary key yourself, then you'd have to run this query on the table:
SET IDENTITY_INSERT [Tablename] ON;
You can read more about this on this thread.

Laravel Nova 3 - Resource Fields Error - BelongsTo - "Trying to get property 'resourceClass' of non-object"

I am new to Laravel's Nova and finding it good so far, however, in some of my Resource Fields I use the "BelongsTo::make" to reference a relationship that has been defined in the Model.
It works well on the Index page which shows the vehicle that it is referenced to and on the Update and Create pages I am expecting to see a Select input generated with so that the user can choose which vehicle they want, however, I am getting the following error:
Trying to get property 'resourceClass' of non-object
Any assistance is greatly appreciated.
Table
CREATE TABLE `vehicle_service` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`vehicle_id` INT(11) NOT NULL,
)
CREATE TABLE `vehicles` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
)
Laravel Model
class VehicleService extends Model
{
protected $table = 'vehicle_service';
protected $casts = [
'last_service_date' => 'date',
];
public function vehicle() {
return $this->belongsTo(Vehicle::class, 'vehicle_id');
}
}
Laravel Nova Resource
class VehicleService extends Resource
{
public static $model = \App\Models\VehicleService::class;
public function fields(Request $request)
{
return [
];
}
public function fieldsForIndex(NovaRequest $request)
{
return [
BelongsTo::make('Vehicle', 'vehicle', 'App\Nova\Vehicle')
->rules('required')
->viewable(false),
];
}
public function fieldsForDetail(NovaRequest $request)
{
BelongsTo::make('Vehicle', 'vehicle', 'App\Nova\Vehicle')
->viewable(false),
}
}
API Path
I came across this suggestion on GitHub but removing the dash between vehicle-services seems to have no impact
/nova-api/vehicle-services/associatable/vehicle?first=false&search=&withTrashed=false&resourceId=2&viaResource=&viaResourceId=&viaRelationship=
Versions:
PHP - v7.4.5
Laravel - v7.15.0
Nova - v3.6.0
This is a known issue with Laravel Nova 3.0, you can check the issue tracker information here:
https://github.com/laravel/nova-issues/issues/2770

Laravel's 5.2.33 Analogue (Data Mapper) orm Query Exception

I'm getting
Undefined column: 7 ERROR: no existe la columna «users_id_seq»
LINE 1: ...ated_at", "updated_at") values ($1, $2) returning "users_id_...
^ (SQL: insert into "users" ("created_at", "updated_at") values (2016-05-26 15:19:02, 2016-05-26 15:19:02) returning "users_id_seq")
When running an insert from a controller
this is my entity class
namespace App\Entities\Users;
use Analogue\ORM\Entity;
class BaseEntity extends Entity
{
private $remember_token;
private $created_at;
private $updated_at;
private $deleted_at;
private $id;
private $name;
private $email;
private $password;
private $identification;
private $cellphone;
Here are getter/setter pairs for each property
}
And this is my map class
namespace App\Entities\Users;
use App\Entities\BaseEntityMap;
class UserMap extends BaseEntityMap
{
protected $primaryKey = 'id';
public $softDeletes = true;
public $timestamps = true;
}
And this is the controller class
namespace App\Http\Controllers\Users;
use App\Http\Controllers\Controller;
use App\Http\ServiceResponse;
use App\Entities\Users\User;
use Faker\Factory as Faker;
use Carbon\Carbon;
use Monolog\Logger as Log;
class UserController extends Controller
{
public function createRandom()
{
$logger = new Log("error");
$randomUsers = array();
for($i=0; $i<1000; $i++)
{
$userMapper = $this->mapper->mapper(User::class);
$faker = Faker::create();
$user = new User();
$user->setName($faker->name);
$user->setEmail($faker->email);
$user->setPassword(bcrypt(rand(1000, 9999)));
$user->setIdentification(bcrypt(rand(1000000, 100000000)));
$user->setCellphone($faker->phoneNumber);
//$user->setCreatedAt(Carbon::now());
//$user->setUpdatedAt(Carbon::now());
//$user->setDeletedAt(null);
$logger->error("user --> " . print_r($user, true));
$userMapper->store($user);
$randomUsers[] = $user->convertToStdClass();
}
$response = new ServiceResponse(0, "createRandom", $randomUsers, "success");
return response()->json($response->toJson());
}
}
And this is what the query looks like on the postgres log file
2016-05-26 10:22:17 COT [4777-1] postgres#ewbackend ERROR: no existe la columna «users_id_seq» en carácter 76
2016-05-26 10:22:17 COT [4777-2] postgres#ewbackend SENTENCIA: insert into "users" ("created_at", "updated_at") values ($1, $2) returning "users_id_seq"
In english it's says that the column "users_id_seq" doesn't exists, but I already check on the db, and that sequence exists.
And this is the sql for the user table
-- Table: public.users
-- DROP TABLE public.users;
CREATE TABLE public.users
(
id integer NOT NULL DEFAULT nextval('users_id_seq'::regclass),
name character varying(255) NOT NULL,
email character varying(255) NOT NULL,
password character varying(255) NOT NULL,
identification character varying(255) NOT NULL,
cellphone character varying(255) NOT NULL,
remember_token character varying(100),
created_at timestamp(0) without time zone,
updated_at timestamp(0) without time zone,
deleted_at timestamp(0) without time zone,
CONSTRAINT users_pkey PRIMARY KEY (id),
CONSTRAINT users_email_unique UNIQUE (email),
CONSTRAINT users_identification_unique UNIQUE (identification)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.users
OWNER TO postgres;
I also check the table (I created with a migration, just add some fields to the migration user example included with laravel 5.2.33) and all columns are there, with the correct types
I try assigning the dates by my self, but that make no difference.
I also try to quit the timestamps=true on my map class but then i see another error in which the query has no fields or values on the postgres log file, and I need the timestamps columns.
The log showings the user instance, shows that all of the data was set correctly.
I also try to put the entity properties public instead of private but that doesn't work.
So I apreciate any ideas on this issue. Also if can you tell me if analogue support postgres transactions (a set of queries that runs as one in order to fail if one of the queries fails or commit only if all the queries were successfull operations )
Analogue Entities use magic setters getters, so you don't have to manually add private properties + getters and setters.
Did you try :
class BaseEntity extends Entity
{
}
And set your column like this :
$user->name($faker->name);
$user->email($faker->email);
etc..
And yes afaik, it does support transactions on Postgres.

Returning virtual columns in Phalcon models

I have a model leads_contents_interactions for the (simplified) table:
CREATE TABLE `leads_contents_interactions` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`lead_content_id` bigint(20) unsigned DEFAULT NULL,
`created_on` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8;
I would like to select these and in addition to the id, lead_content_id, and created_on columns, I would also like it to return a column is_new where that is something like this:
SELECT
id,
lead_content_id,
created_on,
IF(created_on > DATE_SUB(NOW(),INTERVAL 1 DAY), 1, 0) AS is_new
FROM leads_contents_interactions;
Now I am aware I can do this with PHQL, but the leads_contents_interactions would ideally not be queried directly, I want this extra column to be returned when it is queried naturally like:
$leads = $user->getRelated(
'leads',
array(
'Lead.deleted_by IS NULL',
'limit'=>1000
)
);
foreach($leads as $lead) {
foreach($lead->interactions as $interaction) {
echo $interaction->id."\t".$interaction->is_new.PHP_EOL;
}
}
Model for Lead (simplified)
class Lead extends PersendlyModelAbstract {
public function initialize() {
// A lead has multiple interactions, `contents`, through the weak entity `leads_contents`
$this->hasManyToMany(
'id',
'LeadsContents',
'lead_id',
'id',
'LeadsContentsInteractions',
'lead_content_id',
array('alias' => 'interactions')
);
}
}
Model for LeadsContents (simplified)
class LeadsContents extends PersendlyModelAbstract {
public function initialize() {
$this->belongsTo('lead_id', 'Lead', 'id', array('alias' => 'lead'));
$this->belongsTo('content_id', 'Content', 'id', array('alias' => 'content'));
$this->hasMany('id', 'LeadsContentsInteractions', 'lead_content_id');
}
}
Model for LeadsContentsInteractions (simplified)
class LeadsContentsInteractions extends PersendlyModelAbstract {
public function initialize() {
$this->belongsTo('lead_content_id', 'LeadsContents', 'id', array('alias' => 'lead_content'));
}
}
If you are wanting to add a column that doesn't exist on the table, but exists as a business rule (created_on > DATE_SUB(NOW(),INTERVAL 1 DAY), 1, 0) then you need to add that rule in the afterFetch method of the model itself:
http://docs.phalconphp.com/en/latest/reference/models.html#initializing-preparing-fetched-records
class LeadsContentsInteractions extends PersendlyModelAbstract
{
public $isNew;
public function afterFetch()
{
$this->isNew = INSERT BUSINESS LOGIC HERE
}
}
It should however be noted, that if you then use the method toArray() on the record set, that it will only use the columns that exist on the table itself.
http://forum.phalconphp.com/discussion/498/afterfetch-
Overriding toArray() Method for Virtual Fields.
In response to what David Duncan said:
It should however be noted, that if you then use the method toArray()
on the record set, that it will only use the columns that exist on the
table itself.
And to circumvent such Phalcon 'limitation', I created the following method override.
Step 1
Basically, create a BaseModel.php and put the next code there.
/**
* Method override.
*
* This method is inherited from Model::toArray()
* https://docs.phalconphp.com/en/3.2/api/Phalcon_Mvc_Model
*
* We override it here to circumvent a Phalcon limitation:
* https://stackoverflow.com/a/27626808/466395
*
* Basically, the limitation consists that, when one adds 'virtual fields' to a model (for example,
* by way of callback methods like afterFetch()), then using toArray() on that model only returns
* the fields in the database table but not the virtual fields.
*
* #access public
* #param array $columns As per the Model::toArray() method.
* #return array The data of the model, including any custom virtual fields.
*/
public function toArray($columns = null) {
// calls the regular toArray() method
$data = parent::toArray($columns);
// then gets the model's virtual fields, if any
$virtual_fields = [];
if (!empty($this->list_virtual_fields)) {
// iterates, to get the virtual field's name, value, and getter
foreach ($this->list_virtual_fields as $name) {
$getter_name = 'get' . \Phalcon\Text::camelize($name);
$virtual_fields[$name] = $this->{$getter_name}();
}
}
// merges the model's database data with its virtual fields
$data = array_merge($data, $virtual_fields);
return $data;
}
Step 2
Then, in any of your app models, define the list of virtual fields that will be included in the method override above. For example:
public $list_virtual_fields = [
'status_label'
];
You should also define class properties, setters, and getters for those virtual fields. Just an example:
protected $status_label;
public function getStatusLabel() {
return $this->status_label;
}
public function setStatusLabel(string $status_label) {
$this->status_label = $status_label;
return $this;
}
Step 3
Finally, set the value of virtual fields throughout your app. An example:
public function afterFetch() {
$this->setStatusLabel('pending');
}
Note that my code uses getters and setters. You could change that if you wish.

CakePHP: Duplicate entry for key "PRIMARY' for shell script

I am creating a real estate website that has Listing ID's attached to each listing. I am running a script via shell in CakePHP that is parsing a csv file and should be updating any listing that already exists or inserting a new one if it does not.
The problem is that I keep getting a Duplicate entry '###' for key "PRIMARY' where ### is the Listing ID that is being provided by the CSV. This script is being run from the command line.
Here's a smaller version of what my table includes:
CREATE TABLE `listings` (
`ListingID` int(11) NOT NULL,
`AccessibilityYN` varchar(50) DEFAULT NULL COMMENT 'AccessibilityYN',
`BathsFull` int(6) DEFAULT NULL COMMENT 'BathsFull',
`BathsPartial` int(6) DEFAULT NULL COMMENT 'BathsPartial',
`BathsTotal` decimal(5,1) DEFAULT NULL COMMENT 'BathsTotal',
`Beds` int(11) DEFAULT NULL COMMENT 'Beds',
PRIMARY KEY (`ListingID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Here's my Listing Model (notice that I have public $primaryKey = 'ListingID';)
class Listing extends AppModel {
public $name = 'Listing';
public $primaryKey = 'ListingID';
public $belongsTo = array(
'Agent' => array(
'className' => 'Agent',
'foreignKey' => 'AgentID'
)
);
}
Here's the shell I'm running via command line:
class MyShell extends AppShell {
public $uses = array('Listing');
public function update_imported_listings() {
/***SOME CODE HERE TO GET THE $entry FROM THE CSV***/
$this->Listing->ListingID = $entry['ListingID'];
if(!$this->Listing->exists()){
$this->Listing->create();
}
if($this->Listing->save($entry)){
echo "Saved Listing";
} else {
echo "Listing Failed";
}
}
}
I understand that CakePHP usually likes id to be the field used in the database, however I have set $primaryKey = 'ListingID' in my model. I've tried setting ListingID to Auto Increment in the DB but that didn't work.
Anybody have any ideas? I'm fresh out.
Setting ListingID doesnt' do anything
This line is your problem:
$this->Listing->ListingID = $entry['ListingID'];.
Irrespective of what your actual primary key field is in database the primary key value is always specified using Model->id property. As such, change it to:
$this->Listing->id = $entry['ListingID'];
You don't need to call exists
There is not need to explicitly check if record with particular primary key values exists. Cake will automatically update and record instead of creating a new one if the data array passed to save() contains a valid primary key value which exists in db. Just ensure you call create() before saving if you are using save() in a loop.
Don't break CakePHP conventions, use 'id' field as primary key.
http://book.cakephp.org/view/24/Model-and-Database-Conventions
I was getting the same error running a cakePHP shell script, turns out the latest record's ID was at the maximum value allowed by the size of the column (whoever made the table used a medium int for the id column), so auto_increment wasn't working. Changed the column to allow for larger numbers to fix. Probably something obvious, but might help someone out there.

Categories