I have 3 tables:
stations (id,station_name)
products (id,product_name)
product_station (station_id,product_id)
Station Model
protected $fillable = ['station_name'];
public function products(){
return $this->belongsToMany(Product::class);
}
Product Model
protected $fillable = ['product_name'];
public function stations(){
return $this->belongsToMany(Station::class);
}
I already have inserted stations and products and i want to insert
station with it's own product using into Pivot table
AdminProductStationcontroller
public function create()
{
$station = Station::pluck('station_name','id')->all();
$products = Product::pluck('product_name','id')->all();
return view('admin.product_stations.create',compact('station','products'));
}
I think there is error in store function below
public function store(Request $request)
{
$station = new Station();
$product = new Product();
$station->save();
$station->products()->attach($product);
return redirect('/admin/product_stations');
}
So i have got this error
(2/2) QueryException
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'product_id' cannot be null (SQL: insert into product_station (product_id, station_id) values (, 25))
attach() expects a single or an array of ids of the related Model implying that the Model should have been created beforehand.
What you're looking for is the save(Model) method.
$station->products()->save($product);
More on the above in the docs: https://laravel.com/docs/5.8/eloquent-relationships#updating-many-to-many-relationships
You should firstly save
$station = new Station();
$station->save();
$product = new Product();
$product->save();
then
https://laravel.com/docs/6.x/eloquent-relationships#updating-many-to-many-relationships
$station->products()->attach($product->id);
OR
You can try to save like so
$station->products()->save($product);
// Post Model
public function categories()
{
return $this->belongsToMany('App\Category')->withTimestamps();
}
public function tags()
{
return $this->belongsToMany('App\Tag')->withTimestamps();
}
public function store(Request $request)
{
$this->validate($request,[
'title' =>'required',
'image' => 'mimes:jpeg,jpg,bmp,png',
'categories' => 'required',
'tags' => 'required',
'body' => 'required',
'live_demo' =>'required'
]);
$image = $request->file('image');
$slug = str_slug($request->title);
if (isset($image))
{
$currentDate = Carbon::now()->toDateString();
$imagename = $slug.'-'.$currentDate.'-'. uniqid() .'.'. $image->getClientOriginalExtension();
$image_resize = Image::make($image->getRealPath());
$image_resize->resize(1600,1066);
if (!file_exists('storage/uploads/post'))
{
mkdir('storage/uploads/post',0777,true);
}
//$image->move('storage/uploads/post',$imagename);
$image_resize->save('storage/uploads/post/'.$imagename);
}else{
$imagename = "default.png";
}
$post = new Post();
$post->user_id = Auth::id();
$post->title = $request->title;
$post->slug = str_slug($request->title);
$post->image = $imagename;
$post->body = $request->body;
$post->price = $request->price;
$post->live_demo = $request->live_demo;
if(isset($request->status))
{
$post->status =true;
}else
{
$post->status = false;
}
$post->is_approved = true;
$post->save();
$post->categories()->attach($request->categories);
$post->tags()->attach($request->tags);
Toastr::success('Post Successfully Save:)','Success');
return redirect()->route('admin.post.index');
}
// Pivot table create category_post column create category_id, post_id.
// Pivot table create post_tag, and column create post_id, and tag_id
$station->products()->sync($request->products , false);
Related
So i want to fetch data from two tables.
But i got this error :
Here is my Query from Model:
public function tampil_edit($id) {
$this->db->join('tb_m_user', 'tb_m_user.id=tb_m_notaris.id');
$this->db->select('tb_m_notaris.*,tb_m_user.email as email_notaris');
return $this->db->get_where('tb_m_notaris', $id);
}
Here is my Controller :
public function tampiledit($id) {
$id = ['id' => $id];
$title['title'] = 'Notaris | Edit';
$data['notaris'] = $this->m_notaris->tampil_edit($id)->result();
$this->load->view('template/headercss',$title);
$this->load->view('template/sidebar');
$this->load->view('template/navbar');
$this->load->view('master_data/notaris/edit', $data);
$this->load->view('template/footerjs');
}
Here Is what the $id contain:
Check your SQL
WHERE id = 45
^^
This id belongs to which table? I notice there are multiple table (tb_m_notaris,tb_m_user) with id column.
To call function
tampil_edit(45) {} # makesure $id is not an array
In model
public function tampil_edit($id) {
$this->db->select('tb_m_notaris.*,tb_m_user.email as email_notaris');
$this->db->from('tb_m_notaris');
$this->db->join('tb_m_user', 'tb_m_user.id = tb_m_notaris.id');
$this->db->where('tb_m_notaris.id', $id);
return $this->db->get()->result();
}
You should try this.
public function tampil_edit($id) {
$this->db->select('tb_m_notaris.*,tb_m_user.email as email_notaris');
$this->db->join('tb_m_user', 'tb_m_user.id=tb_m_notaris.id');
$this->db->get_where('tb_m_notaris', array('tb_m_notaris.id' => $id));
return $this->db->get()->row_array();
}
update this in your controller
$data['notaris'] = $this->m_notaris->tampil_edit($id);
you should pass like this in your controller
public function tampiledit($id) {
$id = ['tb_m_notaris.id' => $id];
$title['title'] = 'Notaris | Edit';
$data['notaris'] = $this->m_notaris->tampil_edit($id);
$this->load->view('template/headercss',$title);
$this->load->view('template/sidebar');
$this->load->view('template/navbar');
$this->load->view('master_data/notaris/edit', $data);
$this->load->view('template/footerjs');
}
public function tampil_edit($id) {
$this->db->select('tb_m_notaris.*,tb_m_user.email as email_notaris');
$this->db->from('tb_m_notaris');
$this->db->join('tb_m_user', 'tb_m_user.id=tb_m_notaris.id');
$this->db->where('tb_m_notaris.id', $id);
$query = $this->db->get();
return $query->result_array();
}
You need to update your query to this.
As id column exists in both the tables, you need to explicitly provide which table id you want to connect to by mentioning the table name.
I have the following tables and I want to click delete at Pak button which can delete all 3 tables relations.
How can I achieve that?
table Pak : id_pak, pak_name/////
table Church : id_church, church_name, id_pak/////
table Member : id_member, name_member, id_church////
public function actionDelete($id)
{
$this->findModel($id);
$select = Church::find()
->select('church_name')
->where(['id_pak' => $id])
->all();
$a3 = Church::find()
->select('id_church')
->where(['id_pak' => $id])
->all();
$select2 = Member::find()
->select('member_name')
->where(['id_church'=> $a3])
->all();
Church::find()->where(['id_pak' => $id])->one()->delete();
Pak::find()->where(['id_pak' =>$id])->one()->delete();
Member::find()->where(['id_church'=> $a3])->one()->delete();
return $this->redirect(['index','select'=>$select,'select2'=>$select2]);
}
Using Constraints with innoDB Engine
If you are using InnoDB and have added the constraints on delete cascade correctly and defined the respective relations in the models you don't need to worry about the related records in the other tables you just need to find the model in the Pak and delete it.
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
protected function findModel( $id ) {
if ( ($model = Pak::findOne ( $id )) !== null ) {
return $model;
}
throw new NotFoundHttpException ( 'The requested page does not exist.' );
}
Removing Manually
Or if you are not using innoDB or not using constraints for any reason then you can override the beforeDelete() in the ActiveRecord Model for Pak and remove all the child rows for the Pak Model in the Church and override beforeDelete() inside the Church to delete all child rows in Member model and return true from there to continue deleting the actual record in the Pak model
I assume that you have the following relations defined in the Pak model
public function getChurch(){
return $this->hasOne(Church::className(), ['id_pak'=>'id_pak']);
}
and the following inside the Church model
public function getMember(){
return $this->hasOne(Member::className(),['id_church'=>'id_church']);
}
Then override the beforeDelete() in the Pak model
public function beforeDelete() {
$this->church->delete();
return parent::beforeDelete ();
}
and override the beforeDelete() in the Church Model
public function beforeDelete() {
$this->member->delete();
return parent::beforeDelete ();
}
and in your actionDelete() just find the model and call delete
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
There is also a nice article on implementing recursiveDelete() method in a parent model here.
Following code may help you to solve your problem.
public function actionDelete($id)
{
$select = Church::find()
->select('church_name')
->where(['id_pak' => $id])
->all();
$a3 = Church::find()
->select('id_church')
->where(['id_pak' => $id])
->all();
$select2 = Member::find()
->select('member_name')
->where(['id_church'=> $a3])
->all();
// ---------- start ---------------
$park = Park::find()->where(['id_pak' => $id])->one();
if ( $park->delete() ){
Pak::deleteAll('id_pak = :id', [':id' => $id]);
foreach ($a3 as $value) {
Member::deleteAll('id_church = :id', [':id' => $value->id_church ]);
}
}
// ---------- end ---------------
return $this->redirect(['index','select'=>$select,'select2'=>$select2]);
}
I'm using laravel 5.3 with jenssegers/laravel-mongodb package for managing mongodb connections.
I want to check every time a user send a request to register a website in my controller if it's unique then let the user to register his/her website domain.
I wrote below code for validation but What I get in result is :
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'iranad.seat' doesn't exist (SQL: select count(*) as aggregate from `seat` where `domain` = order.org)
my controller code :
public function store(Request $request) {
$seat = new Seat();
$validator = Validator::make($request->all(), [
'domain' => 'required|regex:/^([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/|unique:seat', //validating user is entering correct url like : iranad.ir
'category' => 'required',
]);
if ($validator->fails()) {
return response()->json($validator->messages(), 400);
} else {
try {
$statusCode = 200;
$seat->user_id = Auth::user()->id;
$seat->url = $request->input('domain');
$seat->cats = $request->input('category');
$seat->filter = [];
if($request->input('category') == 'all') {
$obj['cats'] = 'false';
$seat->target = $obj;
} else {
$obj['cats'] = 'true';
$seat->target = $obj;
}
$seat->status = 'Waiting';
$seat->save();
} catch (\Exception $e) {
$statusCode = 400;
} finally {
$response = \Response::json($seat, $statusCode);
return $response;
}
}
}
My Seat Model :
namespace App;
use Moloquent;
use Carbon\Carbon;
class Seat extends Moloquent {
public function getCreatedAtAttribute($value) {
return Carbon::createFromTimestamp(strtotime($value))
->timezone('Asia/Tehran')
->toDateTimeString();
}
}
Obviously The validator is checking if domain is unique in mysql tables which causes this error, How can I change my validation process to check mongodb instead of mysql ?
I solved the problem, The solution is that you should add Moloquent to your model and define database connection :
namespace App\Models;
use Moloquent;
use Carbon\Carbon;
class Seat extends Moloquent
{
protected $collection = 'seat';
protected $connection = 'mongodb';
}
How do I use a custom query in a model using the yii2 framework? I am trying but errors occurs.
I am a beginner in Yii2 Framework.
Here is my login model:
public function getUser($id)
{
$return = User::findBySQL("Select * from User where userType = 'AHP' and userid = '$id';");
return($return['AHPName']);
}
findOne()
Returns a single active record model instance by a primary key or an
array of column values.
$data = User::findOne(['userType' => 'AHP', 'userid' => $id]);
This will find the user whose user type is AHP and whose userid is $id.
public function getUser($id)
{
$data = User::findOne(['userType' => 'AHP', 'userid' => $id]);
return $data['AHPName'];
}
Try with ActiveQuery:
public function getUser($id)
{
$data = User::find()->where(['userType' => 'AHP', 'userid' => $id])->one();
return $data['AHPName'];
}
using custom queries:
public function getUser($id)
{
$sql = "Select * from User where userType = 'AHP' and userid = '.$id.'";
$return = User::findBySQL($sql)->one();
return $return->AHPName;
}
you can try this technique for writing a custom query in yii2
<?php
use yii\db\Query;
$query = new Query();
$query->select(['*'])->from('user')
->where('user.userType=:id',['id'=>'AHP'])
->andWhere('user.userid=:no',['no'=>$id]);
$command = $query->createCommand();
$result = $command->queryAll();
?>
another to do this
User::find()->where('userType = :type and userid = :id',
['type'=>AHP, 'id' => $id])->one();
I like to explain my problem clearly,
Am using wbraganca/yii2-dynamicform
Here create action is working perfectly, but in update action
In the code which i marked, i don't know what i need to do, i dont have such field (addresses) in customer table. am stuck on that.
suppose if i create a variable in model like public $addressess, it makes me the reload the table again, and that cause while update the same form, data's getting reload and form viewing as empty without empty,
if create a function on that name, i don't know what to write on that..
Am simply using code like this
public function getaddressess()
{
}
Create Action Code
public function actionCreate()
{
$modelCustomer = new Customer;
$modelsAddress = [new Address];
if ($modelCustomer->load(Yii::$app->request->post())) {
$modelsAddress = Model::createMultiple(Address::classname());
Model::loadMultiple($modelsAddress, Yii::$app->request->post());
// ajax validation
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ArrayHelper::merge(
ActiveForm::validateMultiple($modelsAddress),
ActiveForm::validate($modelCustomer)
);
}
// validate all models
$valid = $modelCustomer->validate();
$valid = Model::validateMultiple($modelsAddress) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $modelCustomer->save(false)) {
foreach ($modelsAddress as $modelAddress) {
$modelAddress->customer_id = $modelCustomer->id;
if (! ($flag = $modelAddress->save(false))) {
$transaction->rollBack();
break;
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $modelCustomer->id]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
}
return $this->render('create', [
'modelCustomer' => $modelCustomer,
'modelsAddress' => (empty($modelsAddress)) ? [new Address] : $modelsAddress
]);
}
Help me to sort out this problem
$modelsAddress=$modelCustomer->addresses in that example mean array of related Address() instances
public function actionCreate()
{
$modelCustomer = new Customer;
$modelsAddress = $this->getaddressess($modelCustomer->id);
//...................
}
public function getaddressess($id)
{
$model = Address::find()->where(['id' => $id])->all();
return $model;
}
from
public function getaddressess($id)
{
$model = Address::find()->where(['id' => $id])->all();
return $model;
}
Shared above you will also need to add
on your Update view file :
'model' => $model,
'modelsAddress'=>$modelsAddress,
Hope this helps. It worked for me
It should be getAddresses() instead of getaddresses() (although both could work, I'd go with the first one to meet conventions). Or you could set a public $addresses if you don't need extra encapsulation.
suppose if i create a variable in model like public $addressess, it makes me the reload the table again, and that cause while update the same form, data's getting reload and form viewing as empty without empty,
I think you have a validation issue - no validator to mark the field as safe and you see it as empty after posting.
Add public $addresses to your Customer model.
Add "addresses" to your validation rules as safe (or more appropriate validator). This way after posting the form, it probably won't render empty.
This line code ---> $modelsAddress = $modelCustomer->addresses;
is get from model for customer at line ---> public function getAddresses()
this public function line code is code for get array related table from active record method on yii2.
$modelCustomer->addresses the word addresses should come from the $modelCustomer model you must have a relationship to the other table where you add the multiple values. In my example described in the video I have two tables po table and po_items table po_items table has foreign key of po_id. So when you make the Models using gii you will get a relationship in the model that is what you have to use instead of the addresses.
the relationship according my database should be - poItems you will see this at line 14
Add this to Customer Model
public function getAddresses(){
return $this->hasMany(Address::className(), ['id' => 'id']);
}
enter image description hereIn Po.php models:
public function getPoItems()
{
return $this->hasMany(PoItem::className(), ['po_id' => 'id']);
}
In PoController.php
public function actionUpdate($id)
{
$model = $this->findModel($id);
//$modelsPoItem = [new PoItem];
$modelsPoItem = $model->poItems;
if ($model->load(Yii::$app->request->post()) && $model->save())
{
$oldIDs = ArrayHelper::map($modelsPoItem, 'id', 'id');
$modelsPoItem = Model::createMultiple(PoItem::classname(), $modelsPoItem);
Model::loadMultiple($modelsPoItem, Yii::$app->request->post());
$deletedIDs = array_diff($oldIDs, array_filter(ArrayHelper::map($modelsPoItem, 'id', 'id')));
// validate all models
$valid = $model->validate();
$valid = Model::validateMultiple($modelsPoItem) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $model->save(false)) {
if (! empty($deletedIDs))
{
PoItem::deleteAll(['id' => $deletedIDs]);
}
foreach ($modelsPoItem as $modelPoItem)
{
$modelPoItem->po_id = $model->id;
if (! ($flag = $modelPoItem->save(false))) {
$transaction->rollBack();
break;
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $model->id]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
}
return $this->render('update', [
'model' => $model,
'modelsPoItem' => (empty($modelsPoItem)) ? [new PoItem] : $modelsPoItem
]);
}