I just have a little problem. I have a one to many relationship. A team has many users. Many users have a team.
I have six teams of which the user has to choose one. How can I connect the team with the user without creating a new entry in the database 'team'?
User:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id')->unique();
$table->string('name');
$table->integer('team_id')->unsigned()->nullable();
$table->foreign('team_id')->references('id')->on('users')->onDelete('cascade');
$table->string('username')->nullable()->unique();
$table->string('email')->unique();
$table->string('phone')->nullable()->unique();
$table->string('avatar');
$table->string('slug');
$table->string('password');
$table->date('birthday');
$table->boolean('gender');
$table->rememberToken();
$table->timestamps();
});
}
Team:
public function up()
{
Schema::create('teams', function (Blueprint $table) {
$table->increments('id')->unique();
$table->string('name');
$table->string('image');
$table->string('image_thumbnail');
$table->timestamps();
});
}
Controller:
public function storeTeam($request)
{
$user = Auth::user();
$team = Team::findOrFail($request->team_id);
$user->team()->associate($team);
return redirect()->back()->with('success', lang::get('messages.team'));
}
View:
<div class="col-md-12">
<form method="POST" action="{{ URL::route('store.team') }}">
{{ csrf_field() }}
<ul class="row clients-dotted list-inline text-center">
#foreach ($teams as $team)
<li class="col-md-4 col-sm-3 col-6">
<div class="cc-selector">
<input id="team{{$team->id}}" type="radio" name="team" value="{{$team->id}}" />
<label style="background-image:url({{ $team->image_thumbnail }});" class="team-cc" for="team{{$team->id}}"></label>
<p>{{$team->name}}</p>
</div>
</li>
#endforeach
</ul>
<button type="submit" class="mb-50 float-right mr-20 btn btn-shadow-1 btn-primary">weiter</button>
</form>
route:
Route::post('/welcome/team', 'ProfilesController#storeTeam')->name('store.team');
i have a little problem with this and get the error:
Type error:
Type error: Too few arguments to function App\Http\Controllers\ProfilesController::storeTeam(), 0 passed and exactly 1 expected
Assuming that you're storing the team_id on the user model, you can use the associate method to set the primary key on the child -- user in this case
$user->team()->associate($team);
You would pass the selected team to the controller. Doesn't matter how. You can pass it as part of a route, or you can pass the team ID from a form and get it from the request.
You're expecting a variable to literally be passed to the controller called $request. What you want is to inject $request as a dependency. You can do that by typehinting the resolved variable like so:
public function storeTeam(Request $request)
Mind you, you'll need to have use Illuminate\Http\Request; at the top of your file, otherwise you will get errors regarding the Request class.
Related
I have two tables, the activities table and followings table. I want to get "following" activity the date it was created instead of by the date the user was created.
Schema::create('activities', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('user_id')->index();
$table->integer('activity_id')->index();
$table->string('activity_type', 50);
$table->timestamps();
$table->index(['activity_id', 'activity_type']);
});
Schema::create('followings', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('user_id');
$table->unsignedBigInteger('follower_id');
$table->dateTime('followed_date')->nullable();
$table->dateTime('unfollowed_date')->nullable();
$table->timestamps();
$table->unique(['user_id', 'follower_id']);
});
Right now I have this code:
Controller:
$followings = $user->following()->get();
View:
#foreach($followings->sortByDesc('id') as $following)
#foreach($following->user->activity->sortByDesc('id') as $activity)
#if($activity->activity_type == 'App\Thread')
<li class="activity">
<div class="activity-user">
<p class="avatar" style="background-color: {{ $activity->user->color }}">
{{ substr($activity->user->name, 0, 1) }}</p>
</div>
<div class="activity-body">
<h4>{{ $activity->user->name }}
published <a
href="/forums/{{ $activity->activity->channel->slug }}/{{ $activity->activity->slug }}/">
{{ $activity->activity->title }}</a></h4>
<p>
{!! BBCode::parse($activity->activity->body) !!}
</p>
<p class="created-at">
{{-- {{ $activity->activity->created_at->format('l') }}
at
{{ $activity->activity->created_at->format('h:i A') }} --}}
{{ $activity->activity->created_at->format('M j, Y') }}
</p>
</div>
</li>
#endif
#endforeach
#endforeach
Model:
public function following()
{
return $this->hasMany(Following::class);
}
Is there anyway for me to reach the polymorphic table and order by the Activity date instead of by the following() date?
Right now, it returns records based on the user's name in the date they posted it, but I would like it strictly by the activity.
For your scenario, you will be better of with a custom DB query like this, I haven't tested it so you will need to adjust for your use case but basic concept for Laravel is pretty much the same.
$following = Following::join('users', 'followings.user_id', '=','users.id')
->join('activites', 'users.id', '=', 'activities.user_id')
->orderBy('activities.created_at')
->select('followings.*')
->get();
Here's how I did it:
Controller
$followings = $user->following()->get();
foreach($followings as $following) {
foreach($following->user->activity as $activity) {
$followingArray[] = $activity->id;
}
}
//dd($followingArray);
if(!empty($followingArray)){
$following = Activity::whereIn('id', $followingArray)->orderBy('created_at', 'desc')->get();
} else {
$following = '';
}
View:
#if(!empty($following))
#foreach($following as $activity)
what i am trying sync more than one value in the same table so far what i have done is that i have created model of the user and university and define the realtion between them as many to many to many such as the user has many unviersties and universities has many user
in my user model i have defined the realtion such as the
public function University()
{
return $this->belongsToMany(University::class);
}
in my university model
public function user()
{
return $this->belongsToMany(User::class);
}
i have also created a seprate migration since it is the many to many relationship
by the name of university_user
public function up()
{
Schema::create('university_user', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('user_id');
$table->integer('university_id');
$table->timestamps();
});
}
in my controller i am trying to update the profile of user such as
public function ProfileUpdate(Request $request ,User $user)
{
$up=User::find($user->id);
$up->experince=$request->input('experince');
$up->city_id=$request->input('city');
$up->status=$request->input('account-type-radio');
$up->gender=$request->input('gender');
$up->year1=$request->input('year1');
$up->year2=$request->input('year2');
$up->University()->sync($request->Uni1);
$up->University()->sync($request->Uni2);
$up->location()->sync($request->location);
$up->subject()->sync($request->subject);
$up->grade()->sync($request->grade);
$up->update();
return redirect(route('user.index'));
}
in the form
<div class="row">
<div class="col-xl-4">
<div class="submit-field">
<h5>Institute</h5>
<select name="Uni1" id="Uni1">
#foreach($uni as $university)
<option value="{{$university->id}}">
{{$university->name}}
</option>
#endforeach
</select>
</div>
</div>
<div class="row">
<div class="col-xl-4">
<div class="submit-field">
<h5>Institute</h5>
<select name="Uni2" id="Uni2">
#foreach($uni as $uni1)
<option value="{{$uni1->id}}">
{{$uni1->name}}
</option>
#endforeach
</select>
</div>
</div>
The problem is only one value is getting stored in university_user table not two.. please tell me what my mistake is i'll be thank ful to u regards my laravel version is 5.8..
My code keeps returning an error when I deploy to google cloud, but this works locally
Trying to get property 'image_url' of non-object (View: /app/resources/views/library.blade.php)
In my view, I have
#forelse($favorites as $fav)
<div class="col-6 col-md-3">
<a href="{{ route('book', $fav->id) }}">
<img src="{{ $fav->book->image_url }}" alt="trending image" />
</a>
<p class="authorone">{{ $fav->book->author->name }}</p>
<h1 class="book-title">{{ $fav->book->name }}</h1>
#empty
<h2>You have no favourites</h2>
<br/><br/>
Return To Discover
</div>
#endforelse
Here is my controller
public function mylibrary(){
// $mybooks = MyBook::where('user_id', Auth::id())->get();
$favorites = Favorite::where('user_id', Auth::id())->get();
return view('library')->with('favorites', $favorites);
}
In my Favorite Model, I have this
public function book ()
{
return $this->belongsTo(Book::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
In my Book Model, I have this
public function favorites()
{
return $this->hasMany(Favorite::class);
}
In my User Model, I have this
public function favorites(){
return $this->hasMany(Favorite::class);
}
My favorites table
public function up()
{
Schema::create('favorites', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('book_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->timestamps();
});
}
I don't know it's not working when I deploy to google cloud, but it works locally. I can't seems to figure out what I am doing wrong.
I also tried this
public function mylibrary(Book $book){
// $mybooks = MyBook::where('user_id', Auth::id())->get();
$favorites = Favorite::where('user_id', Auth::id())->get();
return view('library')->with('favorites', $favorites)->with('book', $book);
}
My Books schema
Schema::create('books', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->text('about');
$table->string('image');
$table->string('image_url');
$table->string('epub_url');
$table->integer('author_id');
$table->string('publisher');
$table->year('year');
$table->boolean('recommended')->default(0);
$table->timestamps();
});
When querying, you may specify which relationships should be eager
loaded using the with method:
Blockquote
public function mylibrary() {
$data = User::with('favorites', 'favorites.book')->find(Auth::id());
return view('library')->with('userFavorites', $data);
}
You may check for null in chained statements using the Null Coalescing Operator ?? ( introduced in PHP 7) :
//...
<img src="{{ $fav->book->image_url ?? '' }}" alt="trending image" />
//...
Edit
#forelse($userFavorites->favorites as $fav)
<div class="col-6 col-md-3">
<a href="{{ route('book', $fav->id) }}">
<img src="{{ $fav->book->image_url ?? '' }}" alt="trending image"/>
</a>
<p class="authorone">{{ $fav->book->author->name ?? '' }}</p>
<h1 class="book-title">{{ $fav->book->name ?? '' }}</h1>
#empty
<h2>You have no favourites</h2>
<br/><br/>
Return To Discover
</div>
#endforelse
when the admin select a category in <select></select> i want to get its id for insert it in a question table
table questions:
Schema::create('questions', function (Blueprint $table) {
$table->increments('id');
$table->string('question_text');
$table->string('type');
$table->integer('points');
$table->integer('temps_reponse');
$table->integer('categories_id')->unsigned();
$table->foreign('categories_id')->references('id')->on('categories');
$table->timestamps();
});
table categorie :
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('categorie');
$table->timestamps();
});
Question Model
class Question extends Model
{
public function categorie()
{
return $this->belongsTo(Categorie::class, 'categories_id');
}
}
Categorie Model
class Categorie extends Model
{
public function question()
{
return $this->hasMany(Question::class, 'question_id')->withTrashed();
}
}
I am blocked with it for a few hours please any help to solve it
my html
<label class="form-label">Choisir la categorie :</label>
<select class="" id="s2example-1" name="categorie">
<option></option>
#foreach ($categories as $categorie)
<option>{{ $categorie->categorie }}</option>
#endforeach
</select>
In order to send the id instead of the string back to the server, supply the value attribute on each option element: <option value={{$categorie->id}}>{{ $categorie->categorie }}</option>
I have these 2 tables with many to many relationship connected using a junction table. The idea is that I can get the user data to make the user an author in a journal data and it works so far.
User table :
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->integer('phone')->nullable();
$table->string('address')->nullable();
$table->string('password');
$table->rememberToken();
$table->enum('level', ['admin', 'author']);
$table->timestamps();
});
}
Journal table :
public function up()
{
Schema::create('journal', function (Blueprint $table) {
$table->increments('id');
$table->string('title', 255);
$table->text('abstract');
$table->text('file');
$table->integer('id_edition')->unsigned();
$table->timestamps();
});
}
Junction table :
public function up()
{
Schema::create('penulis', function (Blueprint $table) {
// Create tabel penulis
$table->integer('id_user')->unsigned()->index();
$table->integer('id_journal')->unsigned()->index();
$table->timestamps();
// Set PK
$table->primary(['id_user', 'id_journal']);
// Set FK penulis --- user
$table->foreign('id_user')
->references('id')
->on('users')
->onDelete('cascade')
->onUpdate('cascade');
// Set FK penulis --- journal
$table->foreign('id_journal')
->references('id')
->on('journal')
->onDelete('cascade')
->onUpdate('cascade');
});
}
Now I have this view that shows journals data along with the buttons to edit or delete it. What I want to make is that only the user that are entitled as the author of the journal that has the capacity to access these buttons. How do I make it ? below is the view code :
<tbody>
<?php foreach ($journal_list as $journal): ?>
<tr>
<td style="">{{ $journal->title }}</td>
#if (Auth::check())
<td style="width: 130px; overflow: hidden;">
<div class="box-button">
{{ link_to('journal/' . $journal->id . '/edit?edition=' . $edition->id, 'Edit', ['class' => 'btn btn-warning btn-sm']) }}
</div>
<div class="box-button">
{!! Form::open(['method' => 'DELETE', 'action' => ['JournalController#destroy', $journal->id]]) !!}
{!! Form::submit('Delete', ['class' => 'btn btn-danger btn-sm']) !!}
{!! Form::close() !!}
</div>
</td>
#endif
</tr>
<?php endforeach ?>
</tbody>
Sorry for my bad English and if my question is stupid. Thanks!
You need to use a combination of middleware and Gate facade.
Generate a policy
Write a policy
Like this:
public function edit-journal(User $user, Journal $journal)
{
return $user->id === $journal->user_id;
}
public function delete-journal(User $user, Journal $journal)
{
return $user->id === $journal->user_id;
}
3. You can now use the Gate facade with blade
Like this:
#can('edit-journal', $journal)
<div class="box-button">
{{ link_to('journal/' . $journal->id . '/edit?edition=' . $edition->id, 'Edit', ['class' => 'btn btn-warning btn-sm']) }}
</div>
#endcan
#can('delete-journal', $journal)
<div class="box-button">
{!! Form::open(['method' => 'DELETE', 'action' => ['JournalController#destroy', $journal->id]]) !!}
{!! Form::submit('Delete', ['class' => 'btn btn-danger btn-sm']) !!}
{!! Form::close() !!}
</div>
#endcan
You will have to register a middleware for your edit and delete route. Your routes should look like:
//Routes
Route::get('journal/' . {$journal_id} . '/edit', ['as'=>'editJournal','middleware' => 'journal:edit', 'uses'=>'JournalController#edit']
//You need to change your delete form so the action points to that route
Route::delete('journal/' . {$journal_id}, ['as'=>'deleteJournal','middleware' => 'journal:delete', 'uses'=>'JournalController#destroy']
In your middleware, you should have something like:
//Journal Middleware
public function handle($request, Closure $next, $role)
{
$parameters = $request->route()->parameters();
$journal = Journal::findOrFail($parameters['journal_id']);
if (Gate::allows($role.'-journal', $journal)) {
return $next($request);
}else{
abort(403, "You do not have the permission to ".$role." this journal")
}
}
What I;ve done in similar cases is to add a function inside the model that you want to check with all the logic. So for example in your case would be something like:
/Model/Journal.php
public function canBeModifiedByUser($user_id){
//Check all the things that you want
}
Then in the view you can do something like:
if($journal->canBeModifiedByUser($journal->user->id))
Also I would suggest you to check some ACL packages, it might be an overkill for you atm but it might just be what you need.
I would suggest using gates
in your auth service provider you can do
$gate->define('can-modifiy', function ($user) {
// whatever code you want to determine if the user can eg
return $user->hasRole('admin');
});
then in your views you can use #can
#can ('can-modify')
<button>delete</button>
#endcan
This can also be used in your controllers with
$this->authorize('can-modify');
or
Gate::allows('can-modify');
This is in the docs at https://laravel.com/docs/5.3/authorization#writing-gates