Pass the data in the many to many relation ship in laravel - php

I have create a form that will show the user the event title, event description. And the code
public function show($id){
$showevents = Events::findOrFail($id);
return view('events.show',compact('showevents'));
}
This data i pass dont have the user data, but it will give me the specific event data. My question is how to pass the user data along with this?
Because my event table dont have the user information, it all in the user table.
I try {{$showevents->user->name}} in the view form, but it doesnt give me the information of the user.

You will be needing the user-id too if you want to retrieve infomation about the user and send it to the view file..
One thing you can do for getting the user-id anywhere is setting the user-id in Session variable when the user logs-in as:
\Session::set('user_id',$userID);
Then you can get the user-id anywhere in any controller using
$id = \Session::get('user_id');
For example in your case
public function show($id){
$user_id = \Session::get('user_id');
$user = User::findOrFail($user_id);
$showevents = Events::findOrFail($id);
return view('events.show',compact('showevents','user));
}
Now where you will set the Session variable depends entirely upon your code..I used to set after a user has logged in successfully and also rembember to remove session data when logging out as..
\Session::flush();

First of all {{$showevents->user->name}} of course will fail because you don't have any connection between events and user.
If you want to make connection between it you going to need user_id inside event table.
If you want to get user data but don't have any connection, you need to do in seperate query.
$user = User::findOrFail($user_id);
return view('events.show',compact('showevents', 'user'));

You should use Eloquent's relationship functions or wrap them inside you Models relationship functions and use them.
check the Laravel documentation

Related

How to get a custom value using the method Auth in Laravel?

In my laravel project, when i want to get the current user ID, i use this logic bellow:
public function showuserid() {
$userid = Auth::id(); //this is the simplest way i found of how to get the current user's id
return view('perfil/mostrarid')->with('mostrarid', $userid);
}
My problem is, my table 'users' in my database, has an extra column called 'credencial'.
I tried to do $userid = Auth::credencial(); but it doesn't work and i get an error:
Method Illuminate\Auth\SessionGuard::credencial does not exist.
Can i get that value using Auth somehow? Is there any other way, as simple as Auth, to get the value?
My problem is, my table 'users' in my database, has an extra column called 'credencial'.
You need to access a logged-in user's property. To do so, try this:
$credential = Auth::user()->credential;
Now, in order to avoid to throw the error:
Trying to get property 'credencial' of non-object
Make sure that your user is logged-in. You could do this checking it first:
if (Auth::check())
{
$credential = Auth::user()->credential;
}

Laravel 5.5 - Prevent additional attribute to be used during model update

The users table, besides others, have these fields: username, first_name, last_name. Each user can decide whether to show the username or the full name (first + last). This choice is stored inside a "settings" table.
To not perform repeated queries and calls to a function any time I need to show the name, I add the name to display to the user object as it is created, like $user->display_name = ... according to the user's choice.
The problem is that when the user updates the profile, Laravel tries to save this name inside a display_name field into the users' table, which doesn't exist and returns a 500 error. That also happens when the user tries to logout.
Is it possible to avoid that Laravel tries to store that value inside the database?
As suggested in other discussions I have already tried to give a default value to the attribute inside the User model, I've tried to set the attribute as protected, but nothing did work.
This is where the get{...}Attribute() function of a Model comes in handy. Say you want to access $user->full_name without actually saving full_name to the database. Since you have first_name and last_name, you can declare on your User model:
public function getFullNameAttribute(){
return $this->first_name." ".$this->last_name;
}
Laravel will parse what's between get and Attribute into a property available on the model, in this case either $user->full_name or $user->fullName.
To translate this to your use case, you can use something like:
In your User.php model:
public function getDisplayNameAttribute(){
if($this->settings == "use_full_name"){
return $this->first_name." ".$this->last_name;
} else if($this->settings == "use_username"){
return $this->username;
}
return "Not Configured...";
}
Note: You'll have to configure your if statements to determine what to return based on your settings.
Somewhere in a controller or view, you can call $user->display_name to have one of 3 things (determined by the logic/return statements above) displayed:
public function example(){
$user = User::first();
dd($user->display_name);
// $user->first_name." "$user->last_name, $user->username or "Not Configured..."
}
By doing this, when you access your $user, it will have a display_name property available that doesn't actually exist on the model, so you won't run into issues should you call $user->save();

Laravel: Update single field of table using a Resource Controller

I have a Resource Controller (with all the actions: index, create, store, show, edit, update and destroy) and I was wondering what is the best approach to edit a single field column?
Let's say we have a Users table with name, email, password and active (active is a tiny int 0 or 1).
In the users management page, there is a button to activate/deactivate users (makes a request to the server to update the "active" field for the selected user).
Should I create a new method updateStatus in the Controller or is there a way to handle this using the update method?
I don't want, by mistake, allow empty values in the name, email or password when updating the "active" column, so I need to keep the validation rules (in short, all fields are required), but this means when updating the "active" field, I need to pass all the user data in the request.
At this point I'm very confused and all help will be appreciated.
Thanks in advance!
When you send an instance from edit action to the form , all the data will be sent and you can edit one or more columns if you need .
For instance :
public function update(Request $request , $id) {
$data = YourModel::find($id);
$data->someColumn = $request->someColumn;
$data->save();
}
other fields that you didn't send any value for them will be saved as they were before . for this you can set the form like below :
{!! Form::model($yourInstance,['route'=>['someRoute.update','id'=>$yourInstance->id],'method'=>'PATCH',]) !!}
It sounds like you are new to Laravel, and some key concepts can be hard to grasp.
In my opinion the best way to do it would be via a Model class. This is slightly confused by the fact that Laravel has a built in Users model, so I'm going to use a different model as the example of how to update a db field.
php artisan make:model MyData
Will create a new empty model file for the MyData table in app/
The file will look like this:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class MyData extends Model
{
//
}
Even though there's nothing in there, it now allows you do alter the database table using Eloquent.
In your controller add this to make sure the model is included:
use App\MyData as MyData;
The controller should have a method something like this if updating with user input from a form:
public function updateStatus(MyData $myData, Request $request){
$myData->where('id', $request->id)->update(['active' => $request->active]);
}
You could do the exact same thing like this:
public function updateStatus(Request $request){
$data = MyData::find($request->id);
$data->active = $request->active;
$data->save();
}
Both approaches make sense in different circumstances.
See https://laravel.com/docs/5.5/eloquent#updates

Intermediate Table with Laravel

I'm working in a Webapp and I have a problems to work with a intermediate table, these are my tables in mysql:
User:
Integer:id
String:name
String:email
String:phone
Exercise:
Integer:id
String:name
String:description
User_Exercise:
Integer:id
Integer:id_user
Integer:id_exercise
Integer:record
So, what I want to do is that when I create an exercise, it be created one row for each user with the exercise-id that I have created it before. Later the user could change his record in this exercise.
I have thought to create a model to handle the user_exercise's table but I don't know if there is some way to do this better or not.
So, There are some way to do this without create a new model?
PD: Sorry for my terrible english
You don't need a seperate model for User_Exercise
You can use $this->belongsToMany from base Model i.e., User
Note :
For insert process you can get the parent id by
$insertUser = User::create($userData);
then
$insertUser->id for taking the last insert id
And then to retrieve with respect to User_Exercise you shall use $this->belongsToMany from your User Model
Example
Have this in your User Model
public function getUser() {
return $this->belongsToMany('App\User', 'excercise_name', 'user_id', 'excercise_id')->select(array('exercise.id', 'excercise.name'));
}
And Get the data you need from any Controller like this
$userData = User::find($userId)->getUser;

Best way to filter access to controller actions according to a specific client id

Using CakePHP 2.2, I am building an application in which each client has it's own "realm" of data and none of the other data is visible to them. For example, a client has his set of users, courses, contractors and jobs. Groups are shared among clients, but they cannot perform actions on groups. All clients can do with groups is assign them to users. So, an administrator (using ACL) can only manage data from the same client id.
All my objects (except groups, of course) have the client_id key.
Now, I know one way to get this done and actually having it working well, but it seems a bit dirty and I'm wondering if there is a better way. Being early in the project and new to CakePHP, I'm eager to get it right.
This is how I'm doing it now :
1- A user logs in. His client_id is written to session according to the data from the user's table.
$user = $this->User->read(null, $this->Auth->user('id'));
$this->Session->write('User.client_id', $user['User']['client_id']);
2- In AppController, I have a protected function that compares that session id to a given parameter.
protected function clientCheck($client_id) {
if ($this->Session->read('User.client_id') == $client_id) {
return true;
} else {
$this->Session->setFlash(__('Invalid object or view.'));
$this->redirect(array('controller' => 'user', 'action' => 'home'));
}
}
3- Im my different index actions (each index, each relevant controller), I check the client_id using a paginate condition.
public function index() {
$this->User->recursive = 0;
$this->paginate = array(
'conditions' => array('User.client_id' => $this->Session->read('User.client_id'))
);
$this->set('users', $this->paginate());
}
4- In other actions, I check the client_id before checking the HTTP request type this way.
$user = $this->User->read(null, $id);
$this->clientCheck($user['User']['client_id']);
$this->set('user', $user);
The concept is good - it's not 'dirty', and it's pretty much exactly the same as how I've handled situations like that.
You've just got a couple of lines of redundant code. First:
$this->Auth->user('id')
That method can actually get any field for the logged in user, so you can do:
$this->Auth->user('client_id')
So your two lines:
$user = $this->User->read(null, $this->Auth->user('id'));
$this->Session->write('User.client_id', $user['User']['client_id']);
Aren't needed. You don't need to re-read the User, or write anything to the session - just grab the client_id directly from Auth any time you need it.
In fact, if you read http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#accessing-the-logged-in-user it even says you can get it from outside the context of a controller, using the static method like:
AuthComponent::user('client_id')
Though it doesn't seem you'll be needing that.
You could also apply the client_id condition to all finds for a Model by placing something in the beforeFind function in the Model.
For example, in your User model, you could do something like this:
function beforeFind( $queryData ) {
// Automatically filter all finds by client_id of logged in user
$queryData['conditions'][$this->alias . '.client_id'] = AuthComponent::user('client_id');
return $queryData;
}
Not sure if AuthComponent::user('client_id') works in the Model, but you get the idea. This will automatically apply this condition to every find in the model.
You could also use the beforeSave in the model to automatically set that client_id for you in new records.
My answer may be database engine specific as I use PostgreSQL. In my project I used different schema for every client in mysql terms that would be separate database for every client.
In public schema (common database) I store all data that needs to be shared between all clients (objects that do not have client_id in your case), for example, variable constants, profile settings and so on.
In company specific models I define
public $useDbConfig = 'company_data';
In Controller/AppController.php beforeFilter() method I have this code to set schema according to the logged in user.
if ($this->Session->check('User.Company.id')) {
App::uses('ConnectionManager', 'Model');
$dataSource = ConnectionManager::getDataSource('company_data');
$dataSource->config['schema'] =
'company_'.$this->Session->read('User.Company.id');
}
As you see I update dataSource on the fly according to used company. This does exclude any involvement of company_id in any query as only company relevant data is stored in that schema (database). Also this adds ability to scale the project.
Downside of this approach is that it creates pain in the ass to synchronize all database structures on structure change, but it can be done using exporting data, dropping all databases, recreating them with new layout and importing data back again. Just need to be sure to export data with full inserts including column names.

Categories