what's happened with my php artisan migrate - laravel

[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error i
n your SQL syntax; check the manual that corresponds to your MySQL server v
ersion for the right syntax to use near ') on delete cascade on update casc
ade' at line 1 (SQL: alter table users add constraint users_address_id_fo
reign foreign key (address_id) references address () on delete cascade
on update cascade)
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error i
n your SQL syntax; check the manual that corresponds to your MySQL server v
ersion for the right syntax to use near ') on delete cascade on update casc
ade' at line 1
migrate [--bench[="..."]] [--database[="..."]] [--force] [--path[="..."]] [--pac
kage[="..."]] [--pretend] [--seed]
public function up()
{
Schema::create('users',function($table){
$table->increments('id');
$table->string('name',30);
$table->string('phone',11);
$table->integer('age');
$table->string('email',50);
$table->string('marry_status',10);
$table->integer('address_id');
$table->foreign('address_id')->reference('id')->on('address')->onDelete('cascade')->onUpdate('cascade');
$table->integer('points_id');
$table->foreign('points_id')->reference('id')->on('address')->onDelete('cascade')->onUpdate('cascade');
$table->timestamps();
});
}
php migrate --pretend
CreateUsersTable: create table `users` (`id` int unsigned not null auto_increment primary key, `name` varchar(30) not null, `phone` varchar(11) not null, `age` int not null, `email` varchar(50) not null, `marry_status` varchar(10) not null, `address_id` int not null, `points_id` int not null, `created_at` timestamp default 0 not null, `updated_at` timestamp default 0 not null) default character set utf8 collate utf8_unicode_ci
CreateUsersTable: alter table `users` add constraint users_address_id_foreign foreign key (`address_id`) references `address` () on delete cascade on update cascade
CreateUsersTable: alter table `users` add constraint users_points_id_foreign foreign key (`points_id`) references `address` () on delete cascade on update cascade
CreateAddressTable: create table `address` (`id` int unsigned not null auto_increment primary key, `users_id` int not null, `name` varchar(30) not null, `created_at` timestamp default 0 not null, `updated_at` timestamp default 0 not null) default character set utf8 collate utf8_unicode_ci
CreatePointsTable: create table `points` (`id` int unsigned not null auto_increment primary key, `point` int not null, `users_id` int not null, `created_at` timestamp default 0 not null, `updated_at` timestamp default 0 not null) default character set utf8 collate utf8_unicode_ci
i try but i not good
public function up()
{
Schema::create('users',function($table){
$table->increments('id');
$table->string('name',30);
$table->string('phone',11);
$table->integer('age');
$table->string('email',50);
$table->string('marry_status',10);
$table->integer('address_id');
$table->integer('points_id');
$table->timestamps();
});
Schema::table('users',function($table){
$table->foreign('points_id')->references('id')->on('address')->onDelete('cascade')->onUpdate('cascade');
$table->foreign('address_id')->references('id')->on('address')->onDelete('cascade')->onUpdate('cascade');
});
}

You have error in your syntax. You are using reference() method, but the right method is references(). Fix it and I think everything will be ok.

Related

Laravel how to get list of related fields through pivot table

I have 4 tables : peoples, companies, countries and the pivot table company_people (as peoples & companies both belongs to many) which has both people_id and company_id.
In the People model, I have the following functions:
class People extends Model
{
// main company (only one)
public function company()
{
return $this->belongsTo(Company::class);
}
// all other companies
public function companies()
{
return $this->belongsToMany(Company::class);
}
public function country()
{
return $this->belongsTo(Country::class);
}
}
Then in the People controller, I have the following in order to prepare to display a list of all the peoples with the related main company name (only one), country name (only one) and other companies as a list of names. I can do the first 2 but not the last one. How can I do that?
$peoples = People::orderBy($sortField,$sortOrder)
->with(['companies','company','country'])
->get();
foreach ($peoples as $people) {
$people->company = '['.$people->company->company.']'; // main company name
$people->country = '['.$people->country->country.']'; // country name
$people->otherCompanies = ? // list of other company names through pivot table
}
And here all the structure of the 4 tables:
CREATE TABLE `company_people` (
`id` bigint NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`company_id` bigint UNSIGNED NOT NULL,
`people_id` bigint UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `countries` (
`id` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'AA',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`is_active` int NOT NULL DEFAULT '1',
`country` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `peoples` (
`id` bigint UNSIGNED NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`is_active` int NOT NULL DEFAULT '1',
`firstname` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`lastname` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '',
`country_id` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'ZA',
`company_id` bigint UNSIGNED DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci PACK_KEYS=0;
ALTER TABLE `company_people`
ADD PRIMARY KEY (`id`),
ADD KEY `article_id` (`company_id`),
ADD KEY `tag_id` (`people_id`);
ALTER TABLE `countries`
ADD PRIMARY KEY (`id`);
ALTER TABLE `peoples`
ADD PRIMARY KEY (`id`),
ADD KEY `country_id` (`country_id`),
ADD KEY `company_id` (`company_id`);
ALTER TABLE `company_people`
MODIFY `id` bigint NOT NULL AUTO_INCREMENT;
ALTER TABLE `peoples`
MODIFY `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE `peoples`
ADD CONSTRAINT `peoples-company` FOREIGN KEY (`company_id`) REFERENCES `companies` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `peoples-country` FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE `companies`
ADD CONSTRAINT `peoples-country` FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE `company_people`
ADD CONSTRAINT `companies-peoples` FOREIGN KEY (`company_id`) REFERENCES `companies` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `peoples-companies` FOREIGN KEY (`people_id`) REFERENCES `peoples` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
you can use pluck() to get all the company name then toArray() to convert in array like this
$peoples = People::orderBy($sortField,$sortOrder)
->with(['companies','company','country'])
->get();
foreach ($peoples as $people) {
$people->company = '['.$people->company->company.']'; // main company name
$people->country = '['.$people->country->country.']'; // country name
$people->otherCompanies = $people->companies->pluck('name')->toArray(); // list of other company names through pivot table
}
And if you want otherCompanies name as comma seprate then use $people->companies->pluck('name')->join(',');

Importing the sql table shows, Foreign key constraint is incorrectly formed, table made by laravel migration

In Laravel migration, all are working fine. But when I export this table and import in new db, this table shows Foreign Key constraint is incorrectly formed.
sales.sql
-- phpMyAdmin SQL Dump
-- version 4.9.1
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Jul 05, 2020 at 08:19 PM
-- Server version: 10.4.8-MariaDB
-- PHP Version: 7.3.11
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET #OLD_CHARACTER_SET_CLIENT=##CHARACTER_SET_CLIENT */;
/*!40101 SET #OLD_CHARACTER_SET_RESULTS=##CHARACTER_SET_RESULTS */;
/*!40101 SET #OLD_COLLATION_CONNECTION=##COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `inventory_management`
--
-- --------------------------------------------------------
--
-- Table structure for table `sales`
--
CREATE TABLE `sales` (
`id` bigint(20) UNSIGNED NOT NULL,
`sales_no` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
`reference` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`date` date NOT NULL,
`sub_total` double NOT NULL,
`discount` double NOT NULL,
`discount_type` enum('percent','amount') COLLATE utf8mb4_unicode_ci NOT NULL,
`tax` double NOT NULL,
`tax_type` enum('percent','amount') COLLATE utf8mb4_unicode_ci NOT NULL,
`grand_total` double NOT NULL,
`payment_type` enum('no-payment','partial-payment','full-payment') COLLATE utf8mb4_unicode_ci NOT NULL,
`payment_term_id` bigint(20) UNSIGNED DEFAULT NULL,
`notes` text COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_by` bigint(20) UNSIGNED NOT NULL,
`updated_by` bigint(20) UNSIGNED NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`status` enum('paid','void','cancelled','overdue','unpaid') COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`customer_id` bigint(20) UNSIGNED DEFAULT NULL,
`is_item_wise_discount` enum('0','1') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0',
`is_item_wise_tax` enum('0','1') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `sales`
--
ALTER TABLE `sales`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `sales_sales_no_unique` (`sales_no`),
ADD KEY `sales_payment_term_id_index` (`payment_term_id`),
ADD KEY `sales_created_by_index` (`created_by`),
ADD KEY `sales_updated_by_index` (`updated_by`),
ADD KEY `sales_customer_id_index` (`customer_id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `sales`
--
ALTER TABLE `sales`
MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=35;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `sales`
--
ALTER TABLE `sales`
ADD CONSTRAINT `sales_created_by_foreign` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `sales_customer_id_foreign` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `sales_payment_term_id_foreign` FOREIGN KEY (`payment_term_id`) REFERENCES `payment_terms` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `sales_updated_by_foreign` FOREIGN KEY (`updated_by`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
COMMIT;
But all are working fine, When I alter table and do php artisan migrate. It works. The only problem is when exporting table and importing the table in new db. Thank You in advance
are you migrating just one table or the all database? if its just one table, Make sure the other tables exist in the new database with the parent table having information that the other table depending on it needs. let me say if you are migrating sales.sql and its information depends on users say( it has a users_id), then the new database must have the users table in it. Also mind about the datatypes of the column values you are relating in both tables.

Laravel - Eloquent query to display Quiz Result

I am trying to write a query in my controller to display Quiz result for students. I have these tables
CREATE TABLE IF NOT EXISTS `quizz_question` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`topic` varchar(1000) COLLATE utf8_unicode_ci NOT NULL,
`question_code` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`answer1` varchar(100) COLLATE utf8_unicode_ci NULL,
`answer2` varchar(100) COLLATE utf8_unicode_ci NULL,
`answer3` varchar(100) COLLATE utf8_unicode_ci NULL,
`answer4` varchar(100) COLLATE utf8_unicode_ci NULL,
`topic` varchar(1000) COLLATE utf8_unicode_ci NOT NULL,
`correct_answer` varchar(100) COLLATE utf8_unicode_ci NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10 ;
CREATE TABLE IF NOT EXISTS `quizz_attempt` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`student_code` varchar(1000) COLLATE utf8_unicode_ci NOT NULL,
`answer` varchar(100) COLLATE utf8_unicode_ci NULL,
`question_code` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10 ;
The two tables became these two model classes: QuizzQuestion and QuizAttempt.
In quizz_attempt, if a student select an answer (answer), it will take answer and question_code in quizz_attempt and compare with quizz_question.
quizz_attempt.answer = 1 then it will choose the content in answer1 as correct answer
quizz_attempt.answer = 2 then it will choose the content in answer2 as correct answer
quizz_attempt.answer = 3 then it will choose the content in answer3 as correct answer
quizz_attempt.answer = 4 then it will choose the content in answer4 as correct answer
public function gameQualifiers(Request $request)
{
$revenuedetails = DB::table('quizz_attempt as g')
->select(
'g.student_code',
'g.answer'
)
->orderByRaw('g.created_at DESC');
}
I know I need to join the two tables for the result. I started the code in my controller, but don't know how to complete it. i want to write a query to display list of students who choose correct answers
The quiz attempt should have the quizz_question_id as a Foreign Key. This will make it easier down the line to have the two connected.
You can set up two models to match your database tables: QuizzQuestion and QuizzAttempt. You can set up Foreign Keys like so:
QuizzAttempt.php
public function quizzQuestion()
{
return $this->belongsTo('App\QuizzQuestion');
}
And QuizzQuestion.php
public function quizzAttempts()
{
return $this->hasMany('App\QuizzQuestion');
}
So now, you want to get all of the attempts where the answer is correct - you are looking at an instance of QuizzQuestion, e.g.
$question = QuizzQuestion::find(1); // first question
$correctResults = QuizzAttempts::where('quizz_question_id', $question->id)
->where('answer', $question->correct_answer)
->pluck('student_code');`
Now you have all the student codes of the students that got the correct answers.
*** Update
If you cannot change the structure of the tables, you can run the following query:
// 1) find the question you want the answers for
$question = QuizzQuestion::find(1);
// 2) retrieve the correct results
$correctResults = QuizzAttempts::where('question_code', $question->question_code)
->where('answer', $question->correct_answer)
->pluck('student_code');`

Laravel migration script produces multiple primary key columns

The following migration function:
public function up()
{
Schema::create('translations', function (Blueprint $table) {
$table->increments('id');
$table->string('table_name', 32);
$table->string('column_name', 32);
$table->integer('foreign_key', 11)->unsigned();
$table->string('locale', 11);
$table->text('value');
$table->unique(['table_name', 'column_name', 'foreign_key', 'locale']);
$table->timestamps();
});
}
is producing the following SQL query:
create table `translations` (
`id` int unsigned not null auto_increment primary key,
`table_name` varchar(32) not null,
`column_name` varchar(32) not null,
`foreign_key` int unsigned not null auto_increment primary key,
`locale` varchar(11) not null,
`value` text not null,
`created_at` timestamp null,
`updated_at` timestamp null
) default character set utf8mb4 collate utf8mb4_unicode_ci engine = InnoDB ROW_FORMAT=DYNAMIC
Notice the additional auto_increment primary key on the foreign_key field. This is the problem. How do I alter the migrations script so that it does not make foreign_key a second auto_increment primary key column?
(In case this looks familiar, this is from the base code for Voyager.)
This is because the second argument of the integer() method is the step value used for the autoincrement. You can't set the length of a integer column, instead use the column type that better suits your needs.
https://laravel.com/docs/5.4/migrations#columns

yii2 : can't get data from two table with active record

I want get data from two table comments,users.
comments have hasOne relation with users
public function getUser()
{
return $this->hasOne(Users::className(), ['user_id' => 'user_id']);
}
i want get comments.comment_id,comments.comment_content,comments.user_id from comments table and uses.user_name , users.user_display_name from users table to use in gridview widget.
i use
$res = Comments::find()
->select([
'comments.comment_id',
'comments.comment_content',
'comments.user_id',
'users.user_id',
'users.user_display_name',
'users.user_name',
])
->innerJoinWith('user')
->all();
this code get comments field but i can't get users.user_name,users.user_display_name from database.
How should I do it?
note: user table in database is users but when i create model with Gii,relation method declare as getUser(), i don't know why.
update 1:
comments table:
DROP TABLE IF EXISTS `comments`;
CREATE TABLE `comments` (
`comment_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`comment_content` text NOT NULL,
`comment_approved` enum('no','yes') NOT NULL DEFAULT 'no',
`comment_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`comment_parent` bigint(20) unsigned NOT NULL DEFAULT '0',
`sms_id` bigint(20) unsigned NOT NULL DEFAULT '0',
`user_id` bigint(20) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`comment_id`),
KEY `fk_comment_sms_id` (`sms_id`),
KEY `fk_commetn_user_id` (`user_id`),
CONSTRAINT `fk_comment_sms_id` FOREIGN KEY (`sms_id`) REFERENCES `sms` (`sms_id`),
CONSTRAINT `fk_commetn_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;
users table:
CREATE TABLE `users` (
`user_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(60) NOT NULL DEFAULT '',
`user_pass` varchar(64) NOT NULL DEFAULT '',
`user_level` int(11) NOT NULL DEFAULT '1',
`user_email` varchar(100) NOT NULL DEFAULT '',
`user_display_name` varchar(250) NOT NULL DEFAULT '',
`user_phone_number` varchar(11) NOT NULL,
`user_registered` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`user_activation_key` varchar(60) NOT NULL,
`user_status` enum('active','deactive','delete') NOT NULL DEFAULT 'deactive',
PRIMARY KEY (`user_id`),
UNIQUE KEY `u_user_sign` (`user_name`) USING BTREE,
UNIQUE KEY `u_user_email` (`user_email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8;
Not sure how you're displaying or testing if the query returned any data but you should read up on relations in Yii.
Working with Relational Data
Lazy and Eager Loading
With lazy loading the data doesn't exist until you try to access it so may not appear in things like print_r or var_dump
I recommend renaming your tables to comment and user. Read here: Table Naming Dilemma: Singular vs. Plural Names why you should use singular names.
The reason Gii generates getUser and not getUsers is because of the hasOne relationship. It's getting one -user- and not multiple -users-
Are you sure the relationship definition is correct? Is user_id the PK in the users table and the FK in the comments table? And are you sure there is correct data in the DB?

Resources