Laravel 4 Creating Form for adding record with relationship - php

I have created very basic Model. I have persons table and emails table.
Also I have create a link in the persons/show.blade.php ("Add mail").
My models are
class Person extends Eloquent {
protected $table = 'persons';
public function email()
{
return $this->HasMany('Email');
}
}
and
class Email extends Eloquent {
protected $table = 'emails';
public static $rules = array(
'email'=>'required|unique:emails'
);
public function person()
{
return $this->belongsTo('Person');
}
}
How can I pass the $person->id to the new Controller?
In my show.blade.php for Person I added
{{ HTML::linkRoute('email.adduseremail','Προσθήκη Email',array($person->id))}}
and I added to my EmailController
public function adduseremail($id)
{
return View::make('email.createforuser',['id'=>$id]);
}
public function storeforuser($pid)
{
$validator = Validator::make(Input::all(),Email::$rules);
if ($validator->fails()) {
$messages = $validator->messages();
foreach ($messages->all('<li>:message</li>') as $message)
return Redirect::back()->withInput()->WithErrors($messages);
}
$person = Person::FindorFail($pid);
$email = new Email;
$email->email = Input::get('email');
$email->person()->associate($person);
$email->save();
return Redirect::route('person.index');
}
and my createforuser view is
<p>
{{Form::open(['route'=>'email.storeforuser'])}}
<div>
{{Form::label('email', 'Email:')}}
{{Form::input('text', 'email')}}
{{$errors->first('email')}}
</div>
</br>
<div>
{{Form::submit('Submit')}}
</div>
{{Form::close()}}
<p>
I keep getting Trying to get property of non-object (View: /var/www/laravel/app/views/email/show.blade.php)
Is there any example using Form and Models for inserting new objects to the database for 'belongsTo' Relationship? I couldn't find anything complete , just partial examples.

I generally use laravel sessions or laravel cache to tempererally save an id that i need to use later like:
Session::set('personId',$person->id);
Session::get('personId');
The same is for cache except cache will only last for the current request session is persistent for the session
Hope that helps

I am no sure if I 'm supposed to answer my own question but finally I found a solution.
I set two new routes
Route::post('email/adduseremail/{pid}', array('uses'=>'EmailController#adduseremail','as' => 'email.adduseremail'));
Route::post('email/storeforuser/{pid}', array('uses' =>'EmailController#storeforuser','as' => 'email.storeforuser'));
and created the corresponding methods in my Controller
public function adduseremail($id)
{
$pname = Person::Find($id)->name;
$psurname = Person::Find($id)->surname;
return View::make('email.createforuser',array('id'=>$id,'name'=>$pname, 'surname'=>$psurname));
}
and
public function storeforuser($pid)
{
$validator = Validator::make(Input::all(),Email::$rules);
if ($validator->fails())
{
$messages = $validator->messages();
foreach ($messages->all('<li>:message</li>') as $message)
return Redirect::back()->withInput()->WithErrors($messages);
}
$person = Person::FindorFail($pid);
$email = new Email;
$email->email = Input::get('email');
$email->person()->associate($person);
$email->save();
return Redirect::route('person.show',array($person->id));
}
then on my view blade pages I can pass the parameters from View to Form and so on
person.show.blade.php
{{Form::Open(array('route' => array('email.adduseremail', $person->id),'method' => 'POST','style'=>'display:inline;'))}}
{{Form::submit('Add Email')}}
{{Form::close()}}
and
email.createforuser.blade.php
{{Form::open(array('route'=>array('email.storeforuser',$id),'method' => 'POST','style'=>'display:inline;'))}}
{{Form::label('email', 'Email:')}}
{{Form::input('text', 'email')}}
{{Form::submit('Submit')}}
Hope it helps others also

Related

Laravel 5.5 Method save does not exist when updating entries with modified primary key

I am working with laravel 5.5 to update entries. The problem is after changing the primary key 'id', which is elequoent default pk to 'project_id'. adding an item works fine but updating an item is not working properly. Here is the error I am getting.
Method save does not exist.
Here is my Model.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Project extends Model
{
protected $primaryKey = 'project_id';
public function user()
{
return $this->belongsTo(User::class);
}
public function tasks()
{
return $this->hasMany(Task::class);
}
}
Here is my controller function.
public function editProject($id){
$project = Project::where('project_id', $id)->firstOrFail();
$data = ["project_info" => $project];
return view('projects.edit')->with($data);
}
public function updateProject(Request $request){
$data = $request->all();
$validator = Validator::make($data, [
'project_title' => 'required',
'project_description' => 'required',
'project_start_date' => 'required',
'project_end_date' => 'required',
'project_status' => 'required',
]);
$response = [];
if ($validator->fails()){
$response["errors"] = [$validator->messages()->first()];
$response["success"] = false;
return json_encode($response);
}
else{
$project = Project::where("project_id", $request->input('project_id'))->get();
$project->project_title = $request->project_title;
$project->user_id = Session::get('user_id');
$project->project_description = $request->project_description;
$project->project_start_date = $request->project_start_date;
$project->project_end_date = $request->project_end_date;
$project->project_status = $request->project_status;
$project->save();
return redirect('/listProjects');
}
}
Using get() returns a collection. Despite the fact you are passing in a 'unique' ID, the project_id, it will still return a collection - the collection will simply have one element in it.
Subsequently, your code will not work as you have experienced, or at least not without a few changes to make $project reference the first element in the collection.
It's a quick fix though, just change this:
$project = Project::where("project_id", $request->input('project_id'))->get();
to this:
$project = Project::where("project_id", $request->input('project_id'))->first();
By using first(), eloquent will return the first element that matches the query and actually return the element (as opposed to a collection with one element) and so you can directly edit and save it.
Here is the solution I found.
$project_id = $request->input('project_id');
$project = Project::find($project_id);
$project->save();
You can find it by id using
Project::find($id);
Or get the first element like James said:
$project = Project::where("project_id", $request->input('project_id'))->first();

groupBy only gets the first id

I have a many to many relationship between departments and users my pivot table is department_user. I wanted to select all the department_name depending of the user's department using groupBy method to merge all the department_name into one. See below my statement.
$departmentRecipient = DB::table('users')->select('departments.department_name', 'users.id')
->join('department_user', 'users.id', '=', 'department_user.user_id')
->join('departments', 'department_user.department_id', '=', 'departments.id')
->groupBy('departments.department_name')
->get();
Result using die and dump.
As you can see here I have an id of 4 under "Department of Engineering". My main problem is it doesn't fetch all the id under "Department of Engineering". But in my SQL I have id of 5 not only 4. How can I solve this problem? Any help would greatly appreciated. Please see result below.
Output:
This is the output of my list. I wanted to get all the users id belongs to the specific option for the user. But if I choose "Department of Engineering" it only gets the id of 4 not 5. I wanted to get 4 and 5 once.
Controlller:
public function getDocuments()
{
$departmentRecipient = DB::table('departments')->get();
return view ('document.create')->with('departmentRecipient', $departmentRecipient);
}
public function postDocuments(Request $request)
{
$this->validate($request,
[
'title' => 'required|regex:/(^[A-Za-z0-9 ]+$)+/|max:255',
'content' => 'required',
'category' => 'required',
'recipient' => 'required',
]);
$document = new Document();
//Request in the form
$document->title = $request->title;
$document->content = $request->content;
$document->category_id = $request->category;
$document->save();
$user = Auth::user();
foreach($request->recipient as $recipientId)
{
$document->sentToUsers()->sync([ $recipientId => ['sender_id' => $user->id]],false );
}
}
Model
User
public function departments()
{
return $this->belongsToMany('App\Models\Department', 'department_user');
}
Department
public function users()
{
return $this->belongsToMany('\App\Models\User', 'department_user');
}
View
<div class = "form-group">
<label for = "recipient" class = "control-label">Recipient:</label>
<select name = "recipient[]" multiple class = "form-control select2-multi" id = "myUserList">
#foreach ($departmentRecipient as $list)
<option value = "{{ $list->id }}">{{ $list->department_name }}</option>
#endforeach
</select>
</div>
From your given code it seems you are not using Eloquent ORM, you are doing it using Query Builder.
If you don't have a performance concern right now you can do it using separate queries. Like-
$departmentRecipient = DB::table('departments')->all();
foreach($departmentRecipient as $department){
$department->users = DB::table('department_user')->where('department_id',$department->id)->pluck('user_id');
}
But the better way is to use the eloquent with relationships. Define the many to many relationship in your eloquent model of Users and Departments (assuming you have eloquent model for them). You will find details about eloquent relationships at laravel documentation.
Update:
From the update of your post it is actually pretty easy to do what you want. If your Request contains the selected department id then you can do the following:
public function postDocuments(Request $request)
{
$document = new Document();
$document->title = $request->title;
$document->content = $request->content;
$document->category_id = $request->category;
$document->save();
//get the users list of the selected department id
$selected_department = $request->department_id; //this must be included in your POST data
$users = DB::table('department_user')->where('department_id',$selected_department)->pluck('user_id');
//now you have the list of the users id
foreach($users as $user){
// do what you need here
}
}
Update 2:
Following controller code might work for you.
Controller:
public function getDocuments()
{
// I am suggesting here to change the '$departmentRecipient' to '$departmentlist', as it is more meaningful. Also in your view
$departmentlist = DB::table('departments')->get();
return view ('document.create')->with('departmentlist', $departmentlist);
}
public function postDocuments(Request $request)
{
//same as you have till the $document->save()
....
....
//then do this
$recipients = array();
$departments = $request->recipient;
foreach($departments as $department){
$users = DB::table('department_user')->where('department_id',$department)->pluck('user_id');
$recipients = array_merge($recipients, $users);
}
//now you have a complete list of the users from selected departments
//Do as you intend to like this
$user = Auth::user();
foreach($recipients as $recipientId)
{
$document->sentToUsers()->sync([ $recipientId => ['sender_id' => $user->id]],false );
}
}

Display name of select form rather than it's Id (error:Trying to get property of non-object) laravel 5

I have 2 tables tn_client and tn_project, which project have 1 client while client can have many projects, rather than displaying client id on my table, i want display its client name but when i did that its said trying to get property of non-object.
Trying to get property of non-object (View:
C:\xampp\htdocs\PKL\netxcel-activityreport-11b90b878d39\resources\views\project.blade.php)
Above is the full error that i get, and below is the tables
tn_project
tn_client
CONTROLLER
public function index(){
Log::info('Entering index');
return view('project')
->with('title','Project')
->with('projects',Project::with('client','invoice')->get())
->with('clients',Client::all())
->with('invoices', Invoice::all());
}
//get all data
public function getAll(){
return Response::json(
array(
'content' => Project::with('client','invoice')->get(),
'status' => 'success',
)
);
}
public function createOrEdit(){
$currentUsername = Auth::user()->name;
$isUpdate = false;
$projectId = Input::get('prevId');
//populate data
$project = new Project;
if($projectId != ""){
$project = Project::where('cv_id','=',$projectId)->firstOrFail();
$project->cv_updated_by = $currentUsername;
$project->cn_updated_at = Carbon::now();
$isUpdate = true;
} else{
$project->cv_created_by = $currentUsername;
$project->cn_created_at = Carbon::now();
}
$project->cv_id = Input::get('projectId');
$project->cv_name = Input::get('projectName');
$project->cv_client_id = Input::get('clientId');
$project->cn_invoice_method = Input::get('invoiceId');
$project->cn_project_rate = Input::get('projectRate');
$project->cn_note = Input::get('note');
//execute
if($isUpdate){
Log::info("entering update mode");
Project::where('cv_id','=',$projectId)->update(['cv_id'=>$project->cv_id,
'cv_name'=>$project->cv_name,
'cv_client_id'=>$project->cv_client_id,
'cn_invoice_method'=>$project->cn_invoice_method,
'cn_project_rate'=>$project->cn_project_rate,
'cn_note'=>$project->cn_note,
'cn_updated_at'=>$project->cn_updated_at,
'cv_updated_by'=>$project->cv_updated_by]);
}else{
$project->save();
}
return Response::json(
array(
'content' => Project::with('client','invoice')->get(),
'status' => 'success',
)
);
}
Model
PROJECT
<?php
namespace Activity;
use Illuminate\Database\Eloquent\Model;
class Project extends Model {
protected $table = 'tn_project';
public $timestamps = false;
protected $fillable = [
'cv_id',
'cv_name',
'cv_client_id',
'cn_invoice_method',
'cn_project_rate',
'cn_note',
'cn_created_at',
'cv_created_by',
'cn_updated_at',
'cv_updated_by'
];
public function client(){
return $this->belongsTo('Activity\Client','cv_client_id','cn_id');
}
public function invoice(){
return $this->hasOne('Activity\Invoice','cn_id','cn_invoice_method');
}
}
CLIENT
<?php
namespace Activity;
use Illuminate\Database\Eloquent\Model;
class Client extends Model {
protected $table = 'tn_client';
public $timestamps = false;
protected $fillable = [
'cv_name',
'cv_contact',
'cv_email',
'cv_phone',
'cv_address',
'cn_created_at',
'cn_created_by',
'cn_updated_at',
'cn_updated_by'
];
public function project(){
return $this->hasOne('Activity\Project', 'cv_id', 'cn_id');
}
}
VIEW
this is my select form
<div class="col-md-9">
<select name="clientId" id="clientId" class="form-control" placeholder="Select Client">
#foreach ($clients as $client)
<option value='{{$client->cn_id}}'>{{$client->cv_name}}</option>;
#endforeach
</select>
</div>
This is how i called the function to display it in my view
#foreach($projects as $project)
<tr class="odd gradeX">
<td>{{$project->cv_id}}</td>
<td>{{$project->cv_name}}</td>
<td>{{$project->client->cv_name}}</td><!--This is what cause an -->
<td>{{$project->cn_invoice_method}}</td>
<td>{{$project->cn_project_rate}}</td>
<td>{{$project->cn_note}}</td>
<td>
<a class="btn btn-success" title="edit" data-id={{$project->cv_id}} data-action="project-edit"><i class="fa fa-pencil"></i></a>
<a class="btn btn-danger" title="delete" data-id={{$project->cv_id}} data-action="project-delete"><i class="fa fa-times"></i></a>
</td>
</tr>
#endforeach
im still new to laravel, and what did i do wrong that make such an error like that?
I found the answer, i got the reference from here so based on that reference and the basic of x->y->z, we got to check first that x->y have some value in it if yes we got to check whether it's an object or just an array, in my case it was an array so rather doing something like this
{{$project->client->cv_name}}
which is that how to display an object, we should do something like this
{{$project->client['cv_name']}}
and that is how you solve your problem, cheers :D

Eloquent ORM - update and delete not working

I am working on CRUD for my first Laravel project. Displaying and showing items is working fine.
I tried to update the entry with Query to confirm that I can change values in the table and it worked:
DB::update("UPDATE seasons SET title = 'foo' WHERE ID = 1");
My Problem is that neither updating nor deleting entries will work.
<?php
class SeasonAdminController extends \BaseController
{
// WORKS
public function store()
{
$season = new Season;
$season->title = Input::get('title');
$season->save();
Session::flash('message', 'success!');
return Redirect::to('backend/season');
}
// NOT WORKING
public function update($id)
{
$season = Season::find($id);
$season->title = Input::get('title');
$season->save();
Session::flash('message', 'success!');
return Redirect::to('backend/season');
}
// NOT WORKING
public function destroy($id)
{
Season::destroy($id);
Session::flash('message', 'success!');
return Redirect::to('backend/season/');
}
}
My Route is the following:
Route::resource('backend/season', 'SeasonAdminController');
The form-tag from the edit page:
{{ Form::model($season, array('route' => array('backend.season.update', $season->ID), 'method' => 'PUT')) }}
The form for deleting an entry:
{{ Form::open(array('url' => 'backend/season/' . $value->ID, 'class' => 'pull-right')) }}
{{ Form::hidden('_method', 'DELETE') }}
{{ Form::submit('Löschen', array('class' => 'btn btn-danger')) }}
{{ Form::close() }}
What am I missing here. I appreciate you help, thank you!
The error was that I had "ID" instead of "id" as a primary key in the database table. I am not quite sure why this should not work, but I guess it has to do with the default primary key from the Eloquent Model.
public function update($id){
$inputs = Input::only(array('title'));
if (!$id->update($inputs)) {
Session::flash('message', 'Error!');
}else{
Session::flash('message', 'success!');
}
return Redirect::to('backend/season');
}
public function destroy($id){
if($id){
if($id->delete()){
Session::flash('message', 'Success: Deleted!');
}else{
Session::flash('message', 'Error: Not Deleted!');
}
}
return Redirect::to('backend/season');
}
Try it out.
By the way, the $id is not the season id, can't use find($id) on it because it's an object.
Edit:
You should follow this tutorial
https://www.packtpub.com/books/content/laravel-4-creating-simple-crud-application-hours
Because you do not yet understand how to use models in routes.
Take special attention on how forms are built.
Check your model
class Session extends Model{
protected $table = 'session '; //DB table name
protected $primaryKey = 'Id'; //Primary key Name... some time ORM cant identify the primary key
}

Splitting form into two pages causes error

I have setup the laravel resource controller and utilized the edit and update methods to edit user profiles. My profile form turned out to be too long, so I would like to split it into two forms.
The trouble is that the update function appears to be built into the resource controller - I tried just copy the method, add in my inputs and rename it. I updated the routes and view, but received an error. I also tried to have both forms call the same function, but the information that wasn't included in the form was delete from my db.
My question is, how do I split my form into two, so I can update my user profile from two forms instead of one? Any help would be appreciated. Thank you
For reference, here is my ContractorController
public function edit($id)
{
//
// get the contractor
$contractor = Contractor::find($id);
// show the edit form and pass the contractor
return View::make('contractors.edit')
->with('contractor', $contractor);
}
public function update($id)
{
//
// validate
// read more on validation at http://laravel.com/docs/validation
$rules = array(
);
$validator = Validator::make(Input::all(), $rules);
// process the login
if ($validator->fails()) {
return Redirect::to('contractors/' . $id . '/edit')
->withErrors($validator)
->withInput(Input::except('password'));
} else {
// store
$contractor = Contractor::find($id);
$contractor->name = Input::get('name');
$contractor->tag_line = Input::get('tag_line');
$contractor->contact_name = Input::get('contact_name');
//would like to split items below into a separate form:
$contractor->public_email = Input::get('public_email');
$contractor->phone = Input::get('phone');
$contractor->address_1 = Input::get('address_1');
$contractor->city = Input::get('city');
$contractor->state = Input::get('state');
$contractor->zip = Input::get('zip');
$contractor->website = Input::get('website');
$contractor->story = Input::get('story');
$contractor->save();
// redirect
Session::flash('message', 'Successfully updated profile!');
return Redirect::to('contractors');
}
}
Start of form in edit.blade.php
{{ Form::model($contractor, array('route' => array('contractors.update', $contractor->id), 'class' => 'form-horizontal', 'method' => 'PUT')) }}

Categories