I'm new to Laravel so I struggle. I have a comment system that worked perfectly fine but now I want to also add a reply system to it. So the way I decided to do it, is by adding a parent_id column to the comments table and then check if a comment has a parent. But I don't know how exactly the store method, in this case, should work. Here's my database set up for comments:
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->foreignId('post_id')->constrained()->cascadeOnDelete();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->text('body');
$table->timestamps();
});
}
And now a set up for the reply column:
public function up()
{
Schema::table('comments', function (Blueprint $table) {
$table->unsignedBigInteger('parent_id')->nullable();
$table->foreign('parent_id')->references('id')->on('comments');
});
}
Model:
class Comment extends Model{
use HasFactory;
protected $guarded = [];
public function post()
{
return $this->belongsTo(Post::class);
}
public function author()
{
return $this->belongsTo(User::class, 'user_id');
}
public function replies() {
return $this->hasMany('App\Comment', 'parent_id');
}
}
Controller:
public function store(Post $post){
request()->validate([
'body' => 'required'
]);
$post->comments()->create([
'user_id' => request()->user()->id,
'parent_id' => request()->get('id'),
'body' => request('body')
]);
return back();
}
I just don't know how exactly I can get parent_id in the store function so I would appreciate some suggetstions
it should be the comment id that got the reply
something like this
$post->comments()->create([
'user_id' => request()->user()->id,
'parent_id' => request()->get('comment_id'),
'body' => request('body')
]);
I hope it's helpful
use code :
public function store(Post $post) {
request()->validate([
'body' => 'required'
]);
$post->comments()->create([
'user_id' => request()->user()->id,
'parent_id' => request()->get('comment_id'),
'body' => request('body')
]);
return back();
}
Related
This is a continuation of my last question.
I like to create a relationship between a user (with an account type that’s equal to a “profile”) and my job posts. What I did was create a relationship like this in my models (not sure if correct tho)
User.php
public function jobposts()
{
$this->hasMany(JobPost::class)->where('account_type', 'profile');
}
JobPost.php
public function userprofile()
{
$this->belongsTo(User::class)->where('account_type', 'profile');
}
JobPostController.php
public function store(Request $request)
{
$this->validate($request, [
'job_name' => 'required|max:100',
'describe_work' => 'required|max:800',
'job_category' => 'required|not_in:0',
'city' => 'required|not_in:0',
'state' => 'required|not_in:0',
'zip' => 'required|regex:/\b\d{5}\b/',
]);
dd(auth()->user()->jobpost()->job_name);
}
2021_11_20_211922_create_job_posts_table.php
Schema::create('job_posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->contrained()->onDelete('cascade');
$table->string('job_name');
$table->text('describe_work');
$table->string('job_category');
$table->timestamps();
});
Got 2 questions about what I can do in the JobPostController.php.
How do I dd() to test the output?
This seems wrong
dd(auth()->user()->jobpost()->job_name);
How do I add it correctly into the DB like this?
public function store(Request $request)
{
$request->user()
->jobpost()
->create([
'job_name' => $request->job_name
]);
}
I am using Laravel 8 and trying to get an application form to post to two tables in my database
From my 2 database migration files:
public function up() {
Schema::create('applicants', function (Blueprint $table) {
$table->id();
$table->string('apptitle');
$table->string('firstname');
$table->string('middlename')->nullable();
...
$table->timestamps();
});
}
public function up() {
Schema::create('applications', function (Blueprint $table) {
$table->id();
$table->integer('applicant_id');
$table->integer('user_id');
$table->integer('loanAmount');
$table->string('loanTerm');
...
$table->timestamps();
});
}
Models:
class Applicant extends Model {
use HasFactory;
protected $table = 'applicants';
protected $fillable = [
'apptitle', 'firstname', 'middlename'...
];
public function application() {
return $this->hasOne(Application::class);
}
}
class Application extends Model {
use HasFactory;
protected $table = 'applications';
protected $fillable = [
'applicant_id',
'user_id',
'loanAmount',
'loanTerm',
...
];
public function applicant() {
return $this->belongsTo(Applicant::class);
}
}
Controllers:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\Applicants\CreateApplicantRequest;
class ApplicantsController extends Controller {
...
public function store(CreateApplicantRequest $request) {
$applicant = Applicant::create([
'apptitle' => $request->apptitle,
'firstname' => $request->firstname,
'middlename' => $request->middlename,
...
]);
}
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Application;
use App\Models\Applicant;
use App\Models\User;
use App\Http\Requests\Applications\CreateApplicationRequest;
class ApplicationsController extends Controller {
...
public function store(CreateApplicationRequest $request) {
$application = Application::create([
'applicant_id' => $request->applicant_id,
'user_id' => 'required',
'loanAmount' => 'required',
'loanTerm' => 'required',
...
]);
}
}
Requests:
public function rules() {
return [
'apptitle' => 'required',
'firstname' => 'required',
'middlename',
...
];
}
public function rules() {
return [
'applicant_id' => 'required',
'user_id' => 'required',
'loanAmount' => 'required',
'loanTerm' => 'required',
...
];
}
web.php
Route::get('applicants','ApplicantsController#store');
Route::resource('applications', 'ApplicationsController');
Route::get('applications/{application}', 'ApplicationsController#show');
I am continually getting errors: The applicant id field is required. (If I make this field nullable the form does successfully post all other fields to the database.)
This is my first big Laravel project so any help would be greatly appreciated.
Update:
I have gone through the answers provided and am still getting the same error.
I feel the main issue is - when the form is filled out the applicant_id field for the newly created Applicant is not being captured and added to the applications table?
You can store data from one form into 2 tables like this.
Remove use App\Http\Requests\Applicants\CreateApplicantRequest; from your ApplicationsController and run the following cmd commands:
composer dump-autoload
php artisan cache:clear
php artisan config:clear
php artisan view:clear
php artisan route:clear
These commands clear all cache from your project.
Add nullable to your application migration applicant_id:
$table->integer('applicant_id')->nullable();
I finally was able to get my form posting correctly to both databases - a big thank you to all those that have helped me in this journey.
This is my updated store function in my ApplicationsController:
public function store(CreateApplicationRequest $request, Applicant $applicant)
{
$applicant = Applicant::create([
'apptitle' => $request->apptitle,
'firstname' => $request->firstname,
'middlename' => $request->middlename,
...
]);
$application = $applicant->application()->create([
'applicant_id' => $applicant->id,
'user_id' => auth()->id(),
'loanAmount' => $request->loanAmount,
'loanTerm' => $request->loanTerm,
...
]);
// redirect the user
return redirect(route('applications.index'));
}
I hope this answer helps someone else out!
I have a table called messages and users. the users is the default users table generated by laravel auth. for some reason in my postMessage function in my controller when i try the return
return response()->json(['s' => $broadcastMessage, 'r' => $broadcastMessage->MessageOwner()]);
the relationship ship returns an empty object. i know that the MessageOwner relationship works because i use it in a different function and it works fine but i can't figure out why it wont work here? I made sure and it stores the user_id and it's the correct id.
Note that it does return the message.
here is migration up function
Schema::create('messages', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users');
$table->longText('message');
$table->timestamps();
});
here is my message model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Message extends Model
{
protected $table = 'messages';
protected $fillable = [
'user_id', 'message'
];
public function user()
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
public function MessageOwner()
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
public function job()
{
return $this->belongsToMany(Job::class);
}
}
and here is my controller function
public function postMessage(Request $request)
{
try {
$message = Message::create([
'user_id' => $request->input('user_id'),
'message' => $request->input('message')
]);
$job = Job::find($request->input('job_id'));
$job->messages()->attach($message);
$broadcastMessage = Message::find($message->id);
return response()->json(['s' => $broadcastMessage, 'r' => $broadcastMessage->MessageOwner()]);
event(new MessagePushed($broadcastMessage));
return response()->json([
'success' => true,
'message' => 'success',
]);
} catch (\Exception $exception) {
return response()->json([
'success' => false,
'error' => true,
'message' => $exception->getMessage()
], 500);
}
}
You are calling the relationship method, not the it's value.
Try without the ():
return response()->json(['s' => $broadcastMessage, 'r' => $broadcastMessage->MessageOwner]);
Also you should consider using lower_snake_case for all your relationship methods and name the foreign key by relationshio_name_id, so you don't need to manually define the foreign key name, Laravel will automatically guess it.
I'm studying some Laravel and at some point I had to re-migrate the database because I had to change a table. I'm using postman to do testing, and one of the api methods give me the error:
SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: events.user_id (SQL: insert into "events" ("sport", "title", "players", "when", "description", "location", "updated_at", "created_at") values (Hockey, Grass Hockey, 12, 30/09/2018, Come join us, Fairview park, 2018-11-08 22:19:45, 2018-11-08 22:19:45))
so it seems to be a problem with the events.user_id which I changed on a table called Events to have a relationship with the Users table. Some examples I found by researching is on table fields that were not ids, so I don't how to figure this one out, maybe some of you can help me!
here are the migrations for Events and Users:
public function up()
{
Schema::create('events', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
$table->string('sport');
$table->string('title');
$table->decimal('players', 8, 2);
$table->date('when');
$table->mediumText('description');
$table->string('location');
$table->timestamps();
});
}
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Here are the models:
class Event extends Model
{
protected $fillable = [
'sport',
'title',
'players',
'when',
'description',
'location'
];
public function user()
{
return $this->belongsTo('App\User');
}
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function events()
{
return $this->hasMany('App\Event');
}
}
And below is the api method that is giving me the error:
Route::post('/admin/create-event', function (Request $request) {
$data = $request->all();
$event = Event::create(
[
'sport' => $data['sport'],
'title' => $data['title'],
'players' => $data['players'],
'when' => $data['when'],
'description' => $data['description'],
'location' => $data['location'],
]
);
return $event;
});
Thanks guys!
Edit:
Route::middleware('auth:api')->post('/admin/create-event', function (Request $request) {
$user = $request->user();
$data = $request->all();
$event = Event::create(
[
'user_id' => \Auth::user()->id,
'sport' => $data['sport'],
'title' => $data['title'],
'players' => $data['players'],
'when' => $data['when'],
'description' => $data['description'],
'location' => $data['location'],
]
);
return $event;
});
I think you have to add 'user_id' to $fillable of Event class:
class Event extends Model
{
protected $fillable = [
'sport',
'title',
'players',
'when',
'description',
'location',
'user_id'
];
public function user()
{
return $this->belongsTo('App\User');
}
}
You need to pass the user_id:
'user_id' => \Auth::user()->id
The example above requires an authenticated user in the session, but if you are making the request using postman you probably don’t have one.
Anyway, you need to provide the user_id that will be stored in the database.
EDIT
Eloquent's method create will copy to the model only the attributes defined as fillable. So you have two options:
Add user_id to $fillable
Use newInstance instead of create, manually set the user_id with $event->user_id = ..., and manually save the $event model with $event->save();
I'm trying to seed a couple of databases with laravel seeder, but it seems that it skips some fields..
I'm doing it this way:
Item::create(array(
'name' => 'Category 2',
'photo' => 'Description of category 2',
'order' => 1
'price' => 2.30
'category_id' => 1,
));
The fields 'category_id' and order are not setup in the database..
I'm calling the seeder this way
Artisan::call('db:seed',array('--database' => 'tenant_'.$user, '--class' => 'TenantSeeder'));
Any idea why does it happen?
If I use the standard
$item = new Item;
$item->allfields = "its_value";
$item->save();
It works perfectly
UPDATE
Here comes the model:
<?php
class Item extends Model {
//============================================================================
// PARENT VARIABLES
//============================================================================
protected $table = "items";
protected $softDelete = true;
protected $hidden = ['created_at','updated_at'];
protected $fillable = ['name','price','description','photo']; //Items that can be mass assigned
protected $guarded = array('id');
protected static $rules = [
'name' => 'required|min:3',
'price' => '',
'description' => '',
];
//============================================================================
// METHODS
//============================================================================
public function getId() { return $this->getKey(); }
public function getName() { return $this->name; }
public function getPhotoSrc() { return $this->photo; }
public function item_category(){
return $this->belongsTo('Items_category');
}
public function scopeActive($query)
{
return $query->where('active', '=', true);
}
}
And the Scheme
Schema::create('items', function(Blueprint $table)
{
// auto increment id (primary key)
$table->increments('id');
$table->string('name')->default('New Item');
$table->float('price')->default(0);
$table->string('photo')->nullable();
$table->integer('order')->unsigned();
$table->boolean('active')->default(true);
$table->string('description')->nullable();
$table->integer('category_id')->unsigned();
$table->foreign('category_id')->references('id')->on('items_categories')->onDelete('cascade');
// created_at, updated_at DATETIME
$table->timestamps();
$table->softDeletes(); //It is not really deleted, just marked as deleted
});
Any idea?
As User2094178 said,
I didn't have the fields in the $fillable