Hi ! I read other questions but I don't find my answer.
I want to create data but give me this error:
SQLSTATE[HY000]: General error: 1364 Field 'user_id' doesn't have a
default value
Controller:
public function store(BannerRequest $request)
{
Banner::create($request->all());
flash()->success('Success', 'Your banner has been created.');
return back(); // temporary
}
and my Table:
Schema::create('banners', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
$table->string('street', 40);
$table->string('city', 40);
$table->string('zip', 15);
$table->string('country', 40);
$table->string('state', 40);
$table->integer('price');
$table->text('description');
$table->timestamps();
});
and this is my model :
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Banner;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class Photo extends Model
{
protected $table = 'banners_photos';
protected $fillable = ['name', 'path', 'Thumbnail_path'];
protected $file;
public function banners()
{
return $this->belongsTo(Banner::class);
}
public static function formFile(UploadedFile $file)
{
$photo = new static;
$photo->file = $file;
$photo->fill([
'name' => $photo->fileName(),
'path' => $photo->filePath(),
'Thumbnail_path' => $photo->ThumbnailPath()
]);
return $photo;
}
public function fileName()
{
$name = sha1(time() . $this->file->getClientOriginalName());
$extension = $this->file->getClientOriginalExtension();
return "{$name}.{$extension}";
}
public function filePath()
{
return $this->baseDir() . DIRECTORY_SEPARATOR . $this->fileName();
}
public function ThumbnailPath()
{
return $this->baseDir() . '/tn-' . $this->fileName();
}
public function baseDir()
{
return 'images/photos';
}
public function upload()
{
$this->file->move($this->baseDir(), $this->fileName());
$this->makeThumbnail();
return $this;
}
public function makeThumbnail()
{
Image::make($this->filePath())->fit(200)->save($this->ThumbnailPath());
return $this;
}
}
This code worked already and after refactoring become difficult.
Thank for your helps.
According to that message user_id is not set, therefore it's likely not present in $request->all().
If user_id is present, then you might want to check the user_id is in the $fillable property of your Banner model.
If you are trying to assign your banner to the current user, you could do something like this:
$data = $request->all();
$data['user_id'] = $request->user()->id;
Banner::create($data);
Assuming all other data in the BannerRequest is correct and the user is signed in this should work.
SIDE NOTE: ->onUpdate('cascade') looks dangerous, if the user is modified the database will try and drop the banner. not sure if that is your intention.
Solution :
In public function store :
$banner = auth()->user()->publish(new Banner($request->all()));
add public function publish in User model:
public function publish(Banner $banner)
{
return $this->banners()->save($banner);
}
In your migratin you have this
$table->integer('user_id')->unsigned();
the errors is because in your request->all() you don't have an user_id field, if you need it add it, if not in your migration add
$table->integer('user_id')->unsigned()->nullable();
Related
I have a users table, a message table and a user-message table.
i want to get all the messages between the authenticated user and the receiver.
here are the tables and the models:
the users table and model are obvious.
Message model :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Message extends Model
{
protected $fillable = [
'parent_id', 'message', 'type','status',
];
public function user_messages(){
return $this->hasMany('App\UserMessage');
}
public function users(){
return $this->belongsToMany('App\User','user_messages','message_id','sender_id')->withTimestamps();
}
}
User_message model :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class UserMessage extends Model
{
protected $fillable = [
'message_id', 'sender_id', 'receiver_id','type','seen_status','deliver_status',
];
public function message(){
return $this->belongsTo('App\Message');
}
}
Message table :
* #return void
*/
public function up()
{
Schema::create('messages', function (Blueprint $table) {
$table->id();
$table->integer('parent_id')->nullable();
$table->longText('message')->nullable();
$table->integer('type')->default(1)->comment('1 : message , 2 : file');
$table->integer('status')->default(1);
$table->timestamps();
});
}
User_message table :
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('user_messages', function (Blueprint $table) {
$table->id();
$table->integer('message_id');
$table->integer('sender_id');
$table->integer('receiver_id');
$table->integer('type')->default(0)->comment('1 : groupe message , 0 : personal message');
$table->integer('seen_status')->default(0)->comment('1 : seen');
$table->integer('deliver_status')->default(0)->comment('1 : delivered');
$table->timestamps();
});
}
so all i want to know is how the logic inside the controller function will be.
I found the solution :
public function getMessages($id, $ids){
$final_messages_list = array();
$auth_id = $id;
$friend_id = $ids;
$messages = UserMessage::where('sender_id',$auth_id)->where('receiver_id',$friend_id)->orderby('created_at','desc')->get();
foreach($messages as $message){
$final_messages_list[] = $message->message;
}
return response()->json([
'status' => 200,
'messages' => $final_messages_list,
]);
}
I've been tring for hours to define my relations for a completion system but I failed.
I have a table Users and a table Episodes, and I would like to get in my views if the User has completed an episode.
I created a "completions" table with user_id and episode_id and a boolean field called "completed"
Is it a manytomany relation ? I'd like to have something like $episode->completed which gave me True if the logged in user finished the course, but I can't find my way... I just wanna know how to define my relations, not a whole work done.
Thank you very much !!!!
I believe you can tell Laravel what table to use and also query the pivot column.
//user model
public function episodes(){
return $this->belongsToMany( 'App\Episode', 'completions', 'user_id', 'episode_id' );
}
public function completedEpisodes(){
return $this->belongsToMany( 'App\Episode', 'completions', 'user_id', 'episode_id' )
->wherePivot('completed','=', true)->get();
}
//episode model
public function users(){
return $this->belongsToMany( 'App\User', 'completions', 'episode_id', 'user_id' );
}
The alternative would be to create your pivot as episode_user and laravel will auto detect it as the pivot, add a completed boolean to that table and it would function with just:
//user model
public function episodes(){
return $this->belongsToMany('App\Episode');
}
public function completedEpisodes(){
return $this->belongsToMany('App\Episode')
->wherePivot('completed','=', true)->get();
}
//episode model
public function users(){
return $this->belongsToMany('App\User');
}
Query if episode is complete:
//maybe, haven't tried this
//user
public function hasCompletedEpisode($id){
return $this->belongsToMany('App\Episode')->wherePivot('episode_id','=', $id)
->wherePivot('completed','=', true)->get();
}
//episode
public function hasCompletedEpisode($id){
$user_id = Auth::id();
return $this->belongsToMany('App\User')->wherePivot('user_id','=', $user_id)
->wherePivot('completed', true)->get();
}
If I was you, I would use a custom intermediate table. You can implement this as follows:
Migrations
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
Schema::create('episodes', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
Schema::create('watches', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('epsiode_id');
$table->boolean('completed');
$table->timestamps();
});
Models
class User extends Model
{
protected $guarded = [];
public function watchedEpisodes()
{
return $this->hasMany(Episode::class)->using(Watch::class);
}
public function watches()
{
return $this->hasMany(Watch::class);
}
}
class Episode extends Model
{
protected $guarded = [];
public function users()
{
return $this->hasMany(User::class)->using(Watch::class);
}
}
class Watch extends \Illuminate\Database\Eloquent\Relations\Pivot
{
protected $table = 'watches';
protected $guarded = [];
public static function create(User $user, Episode $episode, bool $completed = false)
{
$watch = new self();
$watch->user_id = $user->id;
$watch->epsiode_id = $episode->id;
$watch->completed = $completed;
$watch->save();
return $watch;
}
public function user()
{
return $this->hasOne(User::class);
}
public function episode()
{
return $this->hasOne(User::class);
}
}
Example Use
$user = User::create(['name' => 'Big Watcher']);
$episode1 = Episode::create(['name' => 'Episode 1']);
$episode2 = Episode::create(['name' => 'Episode 2']);
$episode3 = Episode::create(['name' => 'Episode 3']);
$episode4 = Episode::create(['name' => 'Episode 4']);
Watch::create($user, $episode1);
Watch::create($user, $episode2);
Watch::create($user, $episode3);
return $user->watchedEpisodes;
I have problem my has many relation response null.
this is my model
class Diskusi extends Model
{
protected $table = 'tbl_diskusi';
protected $hidden = [
'topic'
];
public function user(){
return $this->belongsTo(User::class,'id_user');
}
public function category(){
return $this->belongsTo(Category::class);
}
public function pets_category(){
return $this->belongsTo(PetsCategory::class);
}
}
this is my another model
class PetsCategory extends Model
{
//
protected $table = 'tbl_pets_category';
public function diskusi(){
return $this->hasMany(Diskusi::class,'id_pets_category');
}
}
and another
class Category extends Model
{
//
protected $table = 'tbl_category';
public function diskusi(){
return $this->hasMany(Diskusi::class,'id_category');
}
}
and this is my migration for Diskusi
class CreateTblDiskusi extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('tbl_diskusi', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title');
$table->string('content');
$table->string('topic');
$table->unsignedBigInteger('id_user');
$table->unsignedBigInteger('id_category');
$table->unsignedBigInteger('id_pets_category');
$table->timestamps();
$table->foreign('id_user')->references('id')
->on('users')->onDelete('cascade');
$table->foreign('id_category')->references('id')
->on('tbl_category')->onDelete('cascade');
$table->foreign('id_pets_category')->references('id')
->on('tbl_pets_category')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('tbl_diskusi');
}
}
the condition is
i want my Diskusi have one category, and one pets_category
but when i create Diskusi like this
public function create(Request $request)
{
$diskusi = new Diskusi;
$diskusi->title = $request->title;
$diskusi->content = $request->content;
$diskusi->topic = $request->topic;
$diskusi->id_user = Auth::user()->id;
$diskusi->id_category = $request->id_category;
$diskusi->id_pets_category = $request->id_pets_category;
if ($request->photo != ''){
foreach ($request->photo as $itemPhoto) {
# code...
$photo = new Photo;
$rand = $this->generateRandomString() . 'jpg';
//taroh foto di server
// file_put_contents('storage/photo/diskusi/' . $rand , base64_decode($request->photo));
$photo->path_photo = $rand;
$photo->save();
}
}
$diskusi->save();
$diskusi->user;
$diskusi->category;
$diskusi->pets_category;
return response()->json([
'success' => true,
'message' => 'posted',
'post' => $diskusi
]);
}
the response like this
please help me, i tried with many tutorial relational laravel but it's not working for me. i dont know where my false, please tell me my false.
*note: sorry for bad english
You've to define your foreign key in relationship.
public function category(){
return $this->belongsTo(Category::class,'id_category','id');
}
public function pets_category(){
return $this->belongsTo(PetsCategory::class,'id_pets_category','id');
}
If you don't pass the foreign key then by default it judges 'category_id' or 'pets_category_id' but you've given id_category and id_pets_category
I am extremely new to Laravel. You could help me with a small problem:
I can not return in a collection, only the value of a specific column in a relation defined in the model. I will explain:
I have 2 tables:
1 - Tomos
2 - Documents
Migrations:
1- Tomos
private $table = 'tomos';
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create($this->table, function (Blueprint $table) {
$table->increments('id');
$table->string('name')->nullable(false);
$table->text('description')->nullable(true);
$table->boolean('active')->default(true);
$table->timestamps();
});
}
2- Documents
private $table = 'documents';
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create($this->table, function (Blueprint $table) {
$table->increments('id');
$table->date('date')->nullable(false);
$table->integer('provider_id');
$table->integer('tomo_id');
$table->string('folio')->nullable(false);
$table->integer('user_id');
$table->text('description');
$table->timestamps();
$table->foreign('provider_id')
->references('id')->on('providers');
$table->foreign('tomo_id')
->references('id')->on('tomos');
$table->foreign('user_id')
->references('id')->on('users');
});
}
Relations
1- Tomo
public function document()
{
return $this->hasMany(Document::class);
}
2- Document
public function tomo()
{
return $this->belongsTo(Tomo::class);
}
Controller
class Documents extends Controller
{
public function read(Request $request)
{
$provider = $request->only('id');
$documents = Document::select(['id', 'date', 'tomo_id', 'description'])
->with([
'tomo' => function ($query) {
$query->select('id', 'name');
}
])->orderBy('date', 'ASC')
->paginate(25);
return $documents;
}
}
I'm getting the following response in JSON:
current_page 1
data […]
0 {…}
id 2
date 2018-12-01
tomo_id 1
description 1
tomo {…}
id 1
name Tomo 1
But ... I do not want the key ('tomo') to return an object, I want it to return the value of the column ('name') as a string. Example:
current_page 1
data […]
0 {…}
id 2
date 2018-12-01
tomo_id 1
description 1
tomo Tomo 1
Thank you very much in advance..
First you need to add protected $appends = array('tomo_name'); as attribute, because this is one that doesn't exist on the model table.
public function getTomoNameAttribute()
{
return $this->tomo()->name;
}
After this, you can access the tomo name like this ->tomo_name
I'm not 100% sure that this code will work with just copy paste, but you might get the idea and work on it a little bit more.
Oh and be aware that loading the attribute, will query the database for that "tomo" every time.
Thank you very much to: Peter and Munteanu Petrisor
In special to : Munteanu Petrisor
I have been able to solve my problem with the solution that you propose to me, previously I had achieved it using 'join':
class Documents extends Controller
{
public function read(Request $request)
{
$provider = $request->only('id');
$documents = Document::join('tomos', 'documents.tomo_id', '=', 'tomos.id')
->join('users', 'documents.user_id', '=', 'users.id')
->where(['provider_id' => $provider])
->paginate(25, array(
'documents.id',
'documents.date',
'documents.folio',
'documents.description',
'tomos.name as tomo',
));
return $documents;
}
}
And now with your help, using attributes works wonders:
Document Model
protected $appends = [
'tomo_name',
'user_fullname'
];
public function getTomoNameAttribute()
{
return $this->tomo()->first()->name;
}
public function getUserFullNameAttribute()
{
return $this->user()->first()->first_name . ' ' . $this->user()->first()->last_name;
}
Document Controller
class Documents extends Controller
{
public function read(Request $request)
{
$provider = $request->only('id');
$documents = Document::select(['id', 'date', 'tomo_id', 'user_id', 'folio', 'description'])
->where(['provider_id' => $provider])
->orderBy('date', 'ASC')
->paginate(25);
return $documents;
}
}
And now it returns the data the way I expected
data […]
0 {…}
id 2
date 2018-12-01
tomo_id 1
user_id 1
folio 1
description 1
tomo_name 1
user_fullname First Last
Thank you so much!
try this
class Documents extends Controller
{
public function read(Request $request)
{
$provider = $request->only('id');
$documents = Document::select(['id', 'date', 'tomo_id', 'description'])
->with('tomo:id,name') // get relationship with id and name
->orderBy('date', 'ASC')
->paginate(25);
return $documents;
}
}
In your controller, try:
$documents->getCollection()->transform(function ($item) {
$item->tomo = $item->tomo->name;
return $item;
});
return $documents;
Do not know which way is better to perform this operations.Having a two tables inquiry_master and inquiry_plan.Already define a relationship.
Migration files:
>> INQUIRY_MASTER
public function up()
{
Schema::create('inquiry_master', function (Blueprint $table) {
$table->increments('id');
$table->dateTime('created_date_time')->nullable();
$table->unsignedInteger('user_id')->nullable();
$table->string('stitch_video_path')->nullable();
$table->enum('completion_status',['Complete','Pending']);
$table->foreign('user_id')->references('id')->on('users');
});
}
>> INQUIRY_PLAN
public function up()
{
Schema::create('inquiry_plan', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('inquiry_id');
$table->string('title_vacation');
$table->string('email');
$table->string('phone_no', 20)->nullable();
$table->dateTime('start_date')->nullable();
$table->dateTime('end_date')->nullable();
$table->foreign('inquiry_id')->references('id')->on('inquiry_master');
});
}
Currently define a function to insert data only on inquiry_plantable.
function which define on my controller.
Controller Code :
public function addactivity(Request $request) {
$validator = Validator::make($request->all(), Inquiryplan::planRules(), Inquiryplan::PlanMessages());
if ($validator->fails()) {
return back()->with('error', "Unable to send contact request.!!")->withInput()->withErrors($validator);
}
$plandetails = Inquiryplan::SaveOrUpdate($request);
if($plandetails !== false) {
return redirect()->route('plan')->with('success', trans('Plan details added successfully.!!'));
} else {
return back()->with('error', "Unable to save plan details.!!")->withInput();
}
}
And finally save function on my model inquiryplan model.
Model code :
<?php
namespace App;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Input;
class Inquiryplan extends Model
{
protected $table = 'inquiry_plan';
protected $fillable = [
'inquiry_id',
'title_vacation',
'email',
'phone_no',
'start_date',
'end_date'
];
public $timestamps = false;
public static function SaveOrUpdate(Request $request) {
try {
$id = $request->get('id', false);
$plandetails = false;
DB::transaction(function () use ($request, &$plandetails, $id) {
$plandetails = $id ? Inquiryplan::findOrFail($id) : new Inquiryplan();
$plandetails->fill($request->all());
try {
$plandetails->save();
} catch (\Exception $ex) {
throw $ex;
}
});
return $plandetails;
} catch (\Exception $ex) {
throw $ex;
}
}}
Before saving a data on inquiry_plan table, one entry should go to the inquiry_master table.How can i do this ?
A couple things. First, Laravel already has exception handlers built into most if not all of it's functionality so providing you own exception is redundant. A good rule of thumb for this is - if you are expecting an error, this is not the case to use an exemption. So you can refactor this code significantly. As for the additional database entry, simply insert it before your inquiry_plan table logic:
public static function SaveOrUpdate(Request $request) {
$id = $request->get('id', false);
$plandetails = false;
DB::transaction(function () use ($request, &$plandetails, $id) {
$planDetails = $id ? Inquiryplan::findOrFail($id) : new Inquiryplan();
//plan_master
$inquiryMaster = ...
//plan_details
$planDetails->fill($request->all());
$planDetails->save();
});
return $planDetails;
}}
Hopefully this helps!
As an aside, I would recommend splitting the create and update tasks into different controller methods...makes the code cleaner and helps for maintainability down the road.