I'm using laravel 5.5 and im trying to add a comment to a post and i get the following error when i submit to the form
"SQLSTATE[23000]: Integrity constraint violation: 1048 Column
'post_id' cannot be null (SQL: insert into comments (comment_body,
user_id, post_id, updated_at, created_at) values (sdsd, 1, ,
2017-12-03 12:29:58, 2017-12-03 12:29:58))
im going to be using: <% %> is for angular, just letting everyone know.
In tinker this works
Comment::create(['comment_body' => 'this works', 'user_id'=> 1, 'post_id'=>8]);
**Route*
Route::post('post/comment', 'CommentController#create');
Post Model
use App\User;
use App\Like;
use App\Comment;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Post extends Authenticatable
{
protected $fillable = [
'title',
'body',
'user_id',
'created_at',
];
public function user()
{
return $this->belongsTo(User::class);
}
public function likes()
{
return $this->hasMany('App\Like');
}
public function comments()
{
return $this->hasMany('App\Comment');
}
Comment Model
class Comment extends Model
{
protected $fillable = [
'comment_body',
'user_id',
'post_id'
];
public function user()
{
return $this->belongsTo('App\User');
}
public function post()
{
return $this->belongsTo('App\Post');
}
}
CommentConroller
public function create(Request $request, Post $post)
{
$data = request()->validate([
'comment_body' => 'required|max:1000'
]);
$data['user_id'] = auth()->user()->id;
$data['name'] = auth()->user()->name;
$data['post_id'] = $post->id;
$post = Comment::create($data);
$response = new Response(json_encode($data));
$response->headers->set('Content-Type', 'application/json');
if(!$response){
return 'something went wrong';
}
return response()->json($data);
}
Html
<div class="comment-class animated bounceInUp" ng-show="writecomment">
<div class="panel-body">
<ng-form ng-model="commentForm" name="commentForm" method="POST" novalidate>
<div class="form-group">
<label>Write a Comment</label>
<textarea ng-model="post.comment" type="text" class="form-control" name="comment_body" cols="2" rows="2"></textarea>
</div>
<button id="eli-style-button" ng-click="addComment(post)" class="btn btn-primary" type="submit">Submit</button>
</form>
</div>
<!-- END Comment form Inside Ng-repeat -->
</div>
<!-- End of ng-repeat post in mypost -->
</div>
Main.js
$scope.addComment = function(post){
$http.post('/post/comment',{
comment_body: post.comment,
}).then(function(result){
console.log(result.data);
$scope.myposts.push(result.data);
});
};
In order to use route model binding, you have to include the post as a parameter in your route:
Route::post('post/{post}/comment', 'CommentController#create');
Then call it like this:
$http.post('/post/' + post.id + '/comment' ...
Right now in your controller you are getting an empty Post instance that has no ID.
Related
I am creating an event, each event will have attendees, I got this working fine, the problem I am having is an attendee can attend the same event twice, which is not good.
Event View
<?php if($this->session->userdata('user_id')): ?>
<hr>
<?php echo form_open('/attendees/add/'.$event['id']); ?>
<input type="hidden" name="user_id" value="<?php echo $_SESSION['user_id']; ?>">
<input type="submit" value="I'm in!" class="btn btn-success">
</form>
<?php endif; ?>
Attendees Controller
<?php
class Attendees extends CI_Controller {
public function add($event_id) {
// Check login
if(!$this->session->userdata('logged_in')){
redirect('users/login');
}
$this->form_validation->set_rules('user_id', 'required|callback_check_userid_eventid');
if($this->form_validation->run() === FALSE){
$this->session->set_flashdata('attendee_not_added', 'You are already on the list.');
redirect('home');
} else {
$this->attendee_model->add_attendee($event_id);
// Set message
$this->session->set_flashdata('attendee_added', 'You have been added to this event.');
redirect('events');
}
}
}
Attendees Model
<?php
class Attendee_model extends CI_Model {
public function __contruct() {
}
public function get_attendees($id = FALSE){
if($id === FALSE) {
$query = $this->db->get('attendees');
return $query->result_array();
}
$this->db->select('attendees.id, attendees.team, attendees.is_goalie, event.id, user.first_name, user.last_name');
$this->db->from('attendees');
$this->db->join('event', 'attendees.event_id = event.id', 'inner');
$this->db->join('user', 'attendees.user_id = user.id', 'inner');
$this->db->where('event.id', $id);
$query = $this->db->get();
return $query->row_array();
}
public function add_attendee($event_id){
$data = array(
'event_id' => $event_id,
'user_id' => $this->session->userdata('user_id')
);
return $this->db->insert('attendees', $data);
}
// Check attendee exists in event
public function check_userid_eventid($event_id, $user_id){
$query = $this->db->get_where('attendees', array('user_id' => $user_id, 'event_id' => $event_id));
if(empty($query->row_array())){
return true;
} else {
return false;
}
}
}
As you can see I tried creating a custom callback on the button form validation but it did not work.
If anyone can point me in the right direction, let me know if I am even somewhat close.
Thanks in advance.
You are not passing the $event_id value to the callback function. Replace your validation with the following line
$this->form_validation->set_rules('user_id', 'User ID', 'required|callback_check_userid_eventid['.$event_id.']');
add following callback function inside the Attendees Controller file
public function check_userid_eventid($user_id, $event_id){
$CI =& get_instance();
$CI->load->database();
$CI->form_validation->set_message('user_id_unique', "Sorry, that %s is already being used.");
return isset($CI->db) ? ($CI->db->limit(1)->get_where('attendees',compact('user_id','event_id'))->num_rows() == 0) : false;
}
Your callback is in a model that form validation knows nothing about. If you look at the docs: callbacks should be in the same controller as the form validation method that uses it.
However, you can use a function in a model as a callback with a different syntax:
$this->form_validation->set_rules(
'username', 'Username',
array(
'required',
array($this->users_model, 'valid_username')
)
);
as documented here.
Finally, on a false return, you need to make sure that you are setting a message as seen in this example:
public function username_check($str)
{
if ($str == 'test')
{
$this->form_validation->set_message('username_check', 'The {field} field can not be the word "test"');
return FALSE;
}
else
{
return TRUE;
}
}
In conclusion: the documentation has all the answers.
Put the call back function into Controller
<?php
class Attendees extends CI_Controller {
public function add($event_id) {
// Check login
if(!$this->session->userdata('logged_in')){
redirect('users/login');
}
$this->form_validation->set_rules('user_id', 'required|callback_check_userid_eventid');
if($this->form_validation->run() === FALSE){
$this->session->set_flashdata('attendee_not_added', 'You are already on the list.');
redirect('home');
} else {
$this->attendee_model->add_attendee($event_id);
// Set message
$this->session->set_flashdata('attendee_added', 'You have been added to this event.');
redirect('events');
}
}
// Check attendee exists in event
public function check_userid_eventid($event_id, $user_id){
$query = $this->db->get_where('attendees', array('user_id' => $user_id, 'event_id' => $event_id));
if(empty($query->row_array())){
return true;
} else {
return false;
}
}
}
I have two table "patient" and "booking" table, and there is a relationship "One to Many" between them, I want to set up a search form in an index_booking page where a user can type a patient_name on it and auto complete show all patient_name from patient table according to WHERE Condition.
This is Booking Model
class Booking extends Eloquent
{
public function patient()
{
return $this->belongsTo('App\Patient');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
This is Patient Model
class Patient extends Eloquent
{
public function booking()
{
return $this->hasMany('App\Booking');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
And i used this code in index page of booking
{!! Form::text('search_text', null, array('placeholder' => 'Search Text','class' => 'form-control','id'=>'search_text')) !!}
i used this code in Booking Controller to make autocomplete to show data
from patient table:
public function autoComplete(Request $request)
{
$patients = Patient::where('company_id', Auth::user()->company_id)
->where('patient_name', 'like', "&{$request->get('term')}&")
->get();
if ($patients->isEmpty()) {
return ['value' => 'No Result Found', 'id' => ''];
}
return $patients->map(function ($patient) {
return [
'id' => $patient->id,
'value' => $patient->patient_name,
];
});
}
And this is Route
Route::get('autocomplete',array('as'=>'autocomplete','uses'=>'BookingController#index'));
Route::get('searchajax',array('as'=>'searchajax','uses'=>'BookingController#autoComplete'));
Javascript code is
<script >
$(document).ready(function() {
src = "{{ route('searchajax') }}";
$("#search_text").autocomplete({
source: function(request, response) {
$.ajax({
url: src,
dataType: "json",
data: {
term : request.term
},
success: function(data) {
response(data);
}
});
},
minLength: 3,
});
});
</script>
when i type any patient name in search box i received a message No Result Found
this is the validator in booking controller :
public function store(Request $request)
{
//Validate Data
$this->validate($request, [
'patient_id'=> 'required|integer',
'booking_date'=> 'required|max:255',
'tybe'=> 'required',
'value'=>'required',
'doctor_name',
'patient_history',
'pharma',
'complaint',
'diagnosis',
'recomind',
'prescription',
'notes',
'document',
'by',
]);
//Insert Data to Database
$booking = new Booking;
$booking->patient_id = $request->patient_id;
$booking->booking_date = $request->booking_date;
$booking->tybe = $request->tybe;
$booking->value = $request->value;
$booking->doctor_name = $request->doctor_name;
$booking->patient_history = $request->patient_history;
$booking->pharma = $request->pharma;
$booking->complaint = $request->complaint;
$booking->diagnosis = $request->diagnosis;
$booking->recomind = $request->recomind;
$booking->prescription = $request->prescription;
$booking->notes = $request->notes;
$booking->document = $request->document;
$booking->by = $request->by;
$booking->save();
//to save multi selection Tags ,dont foget to add [] after -> tags in create post page then write this code here
//$post->tags()->sync($request->tags, false);
//Show Flash Message
Session::flash('success','تم حفظ البياانات');
//Redirect to another Page
return redirect()->route('booking.index');
}
SQL's syntax for matching with LIKE operator is:
WHERE `column` LIKE '%needle%'
Your code, on the other hand, produces the following:
WHERE `column` LIKE '&needle&'
Which is virtually the same as if you had typed:
WHERE `column` = '&needle&'
So what you need to do is to replace & with % in the following line:
->where('patient_name', 'like', "&{$request->get('term')}&")
I'm learning laravel pivot table and here's what I'm doing. I have a student and subject model with many to many relationship. In my pivot table i have included columns for test1, test2 and test3 so that i can use it to store the student's score for each subject. These are my models
class Student extends Model
{
protected $guarded = ['id'];
public function subjects()
{
return $this->belongsToMany(Subject::class);
}
}
class Subject extends Model
{
protected $guarded = ['id'];
public function students()
{
return $this->belongsToMany(Student::class);
}
}
This is my migration
public function up()
{
Schema::create('subjects', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->timestamps();
});
Schema::create('student_subject', function (Blueprint $table) {
$table->integer('student_id');
$table->integer('subject_id');
$table->primary(['student_id', 'subject_id']);
$table->integer('test1')->nullable();
$table->integer('test2')->nullable();
$table->integer('test3')->nullable();
});
}
This is where it all got complicated for me. When a student record is created, user is redirected to an enroll page where subjects are selected for the student.
This is my StudController#store
public function store(Request $request)
{
$student = Student::create(request()->all());
Session::flash('status', "New student's record was added successfully");
Session::put('firstname', request('firstname'));
Session::put('lastname', request('lastname'));
Session::put('student_id', $student->id);
Session::put('class', $student->class_admitted);
return redirect('/enroll');
}
This is the enroll form
<form class="form-horizontal" role="form" method="POST" action="/enroll">
{{ csrf_field() }}
<input type="" name="student_id" value="{{ Session::get('student_id')}}" hidden>
<div class="col-md-6 form-group subjectList">
<ul>
#foreach ($subjects as $subject)
<li><label class="checkbox-inline"><input type="checkbox" name="subject_id[]" value="{{ $subject->id }}"> {{ ucwords($subject->name) }}</label></li>
#endforeach
</ul>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary">
Enroll
</button>
</div>
</div>
</form>
And this is my EnrollController#store
public function store(Request $request)
{
//dd($request);
$student = request('student_id');
foreach ($request->input('subject_id') as $subject) {
$student->subjects()->attach($subjects);
}
}
I'm confused as to how I can do insert into the pivot table.
You can add an array in your attach() method, like this:
->attach($subjectId, ['test1' => 1, 'test2' => 2]);
The attach() method will create the entry in the pivot table, the additional attributes will be added.
You can also pass an array of subjects to attach(), like this:
->attach([1 => ['test1' => 1, 'test2' => 2], 2 => ['test1' => 3, 'test2' => 4]]);
And when you need to update the pivot data you can use sync().
As far as I can see now, you do not have anything in your form besides the subject, so I assume you want to update the pivot data later on.
Also, you might want to add some additional validation there on both the student and the subjects.
public function store(Request $request)
{
// making sure student exists
$student = Student::findOrFail(request('student_id'));
$subjectIds = Subject::whereIn('id', $request->input('subject_id', []))
->get()
->pluck('id')
->all();
$student->subjects()->attach($subjectIds);
// you can also use sync here, that way it will add new subjects, keep the ones that already exist (and are posted) and remove subjects not in post
// $student->subjects()->sync($subjectIds);
}
I am trying to retrieve data from the database by user_id. My view shows this error : Trying to get property of non-object. dd() return null.
This is my Controller :
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use App\Complain;
use App\Feedback;
use App\Item;
use Illuminate\Support\Facades\Redirect;
use Session;
use Auth;
class ProfileController extends Controller
{
public function profile($id){
$complain = Complain::find($id);
dd($complain);
return view('user.profile')->with(['complains' => User::find($id)->complains]);
}
}
This is my User Model :
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\Model;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'surname', 'regnumber', 'course', 'department', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function complains()
{
return $this->hasMany('App\Complain');
}
}
This is my Complain Model.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Complain extends Model
{
protected $fillable = [
'user_id', 'title', 'body', 'name', 'regnumber'
];
public function user(){
return $this->belongsTo('App\User');
}
}
This is my view :
#foreach($complains as $complain)
<div>
<h3 class="operator-complain-title">Title: </h3>
<p>{{ $complain->title }}</p>
<h3 class="operator-complain-title">Complain:</h3>
<p>{{ $complain->body }}</p>
</div>
<hr>
#endforeach
The user_id is a foreign key. How do I successfully show complains(data) based on the user_id?
This is my users table:
id | name | email | password
7 John email password
This is my complains table :
id | user_id | title | body
5 7 complain 1 Complain 1
Anyone with ideas please share.
As I understand You want to get complains by user $id.
So doing Complain::find($id) will not return user's complain, cuz find gets by id field.
But You want to get complains by user_id field.
So for that case: Complain::whereUserId($id)->get()
Check this one (recommended when You're going to show user's data and it's complains):
public function profile(Request $request, $id){
$User = User::with(['complains'])->find($id);
if(!$User) return abort(404, 'User with id:'.$id.' not found');
return view('user.profile')->with(['user' => $User, 'complains' => $User->complains]);
}
or this one (if You're going to show complains only):
public function profile(Request $request, $id){
$complains = Complain::whereUserId($id)->get();
if(!$complains) return abort(404, 'No complains for user (id:'.$id.') found');
return view('user.profile')->with(['complains' => $complains]);
}
In case of $id is name of user:
public function profile(Request $request, $name){
$User = User::with(['complains'])->whereName($name)->first();
if(!$User) return abort(404, 'User with name:'.$name.' not found');
return view('user.profile')->with(['user' => $User, 'complains' => $User->complains]);
}
You would try to check first if the object is null or empty before trying to consume it like
<?php
$var = 0;
// Evaluates to true because $var is empty
if (empty($var)) {
echo '$var is either 0, empty, or not set at all';
}
// Evaluates as true because $var is set
if (isset($var)) {
echo '$var is set even though it is empty';
}
?>
public function profile($id)
should be
public function profile(Request $request)
And on Eloquent
$complain = Complain::find($request->id);
Or get query from segment. Example domain/id/ = id from slug number 1
$complain = Complain::find($request->segment(1));
I am trying to track Semi-private tennis lesson records using Laravel 5.3 and mysql. I am attempting to follow the example set in the Laravel 5 Many to Many tutorial. I have a Players model that I am trying to sync with a Sharedlessonhours table via a Player_Sharedlessonhours pivot table. In the code my sharedlessonhours table gets an inserted record, but the pivot table does not. Sorry to be so verbose, but I want to be clear about what's happening.
First the table structure.
public function up()
{
Schema::create('sharedlessonhours', function (Blueprint $table) {
$table->increments('id');
$table->date('signup_date');
$table->integer('packages_id')->unsigned();
$table->timestamps();
});
Schema::table('sharedlessonhours', function (Blueprint $table) {
$table->foreign('packages_id')->references('id')->on('packages');
});
Schema::create('player_sharedlessonhour', function (Blueprint $table)
{
$table->integer('sharedlessonhours_id')->unsigned();
$table->integer('players_id')->unsigned();
$table->timestamps();
});
Schema::table('player_sharedlessonhour', function (Blueprint $table) {
$table->foreign('sharedlessonhours_id')->references('id')->on('sharedlessonhours')->onDelete('cascade');
$table->foreign('players_id')->references('id')->on('players')->onDelete('cascade');
});
}
The create and store methods:
public function createSharedLessonhours()
{
$players = Players::orderBy('lname')->pluck('fname', 'id');
$packages = Packages::orderBy('name')->pluck('name','id');
return view('admin.lessonhours.sharedlessonhours', compact('players', 'packages'));
}
public function storeSharedLessonhours(Request $request)
{
$sharedlessonhours = SharedLessonhours::create($request->all());
$sharedlessonhours->players()->attach($request->input('players'));
}
The Form:
<div class="col-md-4 col-sm-5">
{!! Form::open(['url' => 'sharedlessonhours']) !!}
<div class="form-group">
{!! Form::label('players', 'Player(s):') !!}
{!! Form::select('players[]', $players, null, ['class' => 'form-control', 'multiple']) !!}
</div>
<div class="form-group">
{!! Form::label('signup_date', 'Signup Date:') !!}
{!! Form::text('signup_date', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
{!! Form::label('packages_id', 'Lesson Package:') !!}
{!! Form::select('packages_id', $packages, null, ['class' => 'form-control', 'placeholder' => 'Choose Package']) !!}
</div>
<div class="form-group">
{!! Form::submit('Signup', ['class' => 'btn btn-default form-control']) !!}
</div>
{!! Form::close() !!}
</div>
The screenshot of the select box for the player ids:
And screenshot for error:
I am wondering if the array is simply in the incorrect order? dd($request) shows that everything is being collected from the form and but looking at the error page seems like it is trying to insert data into the wrong fields. The line that has (3,4) wouldn't be the correct order if that matters to mysql. I tried flipping the columns in mysql, but it didn't help.
I am very confused right now.
UPDATE:
First I will share the requested code then share further steps I have taken to debug.
Players model code:
namespace App;
use Illuminate\Database\Eloquent\Model;
use Collective\Html\Eloquent\FormAccessible;
use Carbon\Carbon;
class Players extends Model
{
public $table = "players";
protected $fillable = array('fname', 'lname', 'gender', 'birthdate');
public function users()
{
return $this->belongsTo('App\User', 'users_id');
}
public function lessonHours()
{
return $this->hasMany('App\Lessonhours', 'players_id');
}
public function sharedlessonhours()
{
return $this->belongsToMany('App\SharedLessonhours', "player_sharedlessonhour","players_id", "sharedlessonhours_id" );
}
public function getFullName($id)
{
return ucfirst($this->fname ) . ' ' . ucfirst($this->lname);
}
protected $dates = ['birthdate'];
public function setBirthdateAttribute($value)
{
$this->attributes['birthdate'] = Carbon::createFromFormat('m/d/Y', $value);
}
}
SharedLessonhours:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Collective\Html\Eloquent\FormAccessible;
use Carbon\Carbon;
class SharedLessonhours extends Model
{
use FormAccessible;
protected $fillable = array('signup_date', 'packages_id');
public $table = "sharedlessonhours";
public function players()
{
return $this->belongsToMany('App\Players', "player_sharedlessonhour", "players_id", "sharedlessonhours_id");
}
public function sharedhoursused()
{
return $this->hasMany('App\SharedHoursused', 'id');
}
public function packages()
{
return $this->belongsTo('App\Packages');
}
public function setSignUpDateAttribute($value)
{
$this->attributes['signup_date'] = Carbon::createFromFormat('m/d/Y', $value);
}
}
I attempted to add a different record after changing the columns in mysql and get the error again. I switched the columns back and the error continues, eve`n after restarting tinker.
In addition to customizing the name of the joining table, you may also customize the column names of the keys on the table by passing additional arguments to the belongsToMany method. The third argument is the foreign key name of the model on which you are defining the relationship, while the fourth argument is the foreign key name of the model that you are joining to
From laravel documentation for Many-To-Many relationship.
Accordingly the definition of players relationship in your SharedLessonhour model should be as
public function players()
{
return $this->belongsToMany('App\Players', "player_sharedlessonhour", "sharedlessonhours_id", "players_id");
}
Try changing the definition and see. I haven't tested but this seems to be the cause for constraint violation.