Laravel: How to dynamically create and name views? - php

I am making a website for college administration where professors log in and assign marks to the students they are teaching.
There's a table, called "IA_Marks" in my database:
|Student_ID|Subject_Code|Name|Marks1|Marks2|Marks3|Semester|Division|
There's also a table called "Classroom_Mapper" in my database, that helps map a professor to a classroom, with a subject:
|Prof_ID|Subject_Code|Semester|Division|
This is a method in my controller:
public function showTable(){
$sem = DB::table('classroom_mappers')->where('Prof_ID', auth()->user()->PID)->pluck('semester');
$division = DB::table('classroom_mappers')->where('Prof_ID', auth()->user()->PID)->pluck('division');
$data = DB::table('iamarks')->where([['semester','=',$sem],['division','=',$division]])->get();
return view('ia',compact('data'));
}
Using this, I can fetch rows that belong to the professor who has logged in.
But, there's a problem.
Say the professor teaches two subjects, in two semesters. Then, the where clause will return multiple results from the mapper table.
For example:
select semester from classroom_mapper where Prof_ID=auth()->user()->Prof_ID
output:
8
5
Then the students from both 5th and 8th semester will be shown on his dashboard. Our target semester was, say 5th. Then it'll be a problem.
Registering for a subject, is done as shown here:
form screenshot
Let's call the subject being registered in the screenshot "SUBJECT 4".
It is a subject for the 5th semester, division A.
I want to dynamically make a button(SUBJECT 4) on the dashboard, which when clicked, sends the semester(5) and division(A) of choice to the controller.
Dashboard Screenshot
This button should open a newly made page with name of the subject(subject4.blade.php), where the database table contents for target semester and division(5 and A) will be shown.
How do I make this dynamic view creating button which sends specific info to controller? Is it even possible?

There are a few ways to do this with Laravel, but my goto is usually to create a single blade template for each view (dashboard, subject, etc.) that can be dynamically populated -- assuming that the layout for each subject view is the same.
In your dashboard view, you could generate a url for each button that uses a format like this: http://cas.jce.in/subject/semester/5/division/a/
Next, create a route that uses a couple of paramaters, something like this:
Route::get('/subject/semester/{semester_id}/division/{division_id}', 'ControllerName#showSubject');
More info here: https://laravel.com/docs/5.8/routing#required-parameters
Then in your controller, add a showSemester function like this:
function showSubject($semester_id, $division_id){
$data = DB::table('table_name')->where('semester', '=', $semester_id)->where('division', '=', $division_id)->first();
return view('subject', ['data'=>$data, 'semester'=>$semester_id, 'division'=>$division_id]);
}
Your route parameters are available to the controller, in order of appearance. So we can add $semester_id and $division_id as the first two parameters of our function. Next, we'll to the database work to retrieve the data we need before returning everything to a view.
Note here that we're using a single view rather than dynamically selecting one. You could create individual views for each subject, but im thinking you probably don't need to unless the layout of each one is unique in some way. In that case, you can simply do something like this, but I'd generally try to avoid it.
$view = 'subject'.$data->subject_id;
return view($view, ['data'=>$data, 'semester'=>$semester_id, 'division'=>$division_id]);
Also, just a quick note ... you may consider adjusting your database queries from above to use a select statement rather than pluck. The end result is the same, but using a select can boost performance by only loading the data you want ... rather than loading everything up front and throwing most of it away.
$sem = DB::table('classroom_mappers')->where('Prof_ID', Auth()->user()->PID)->pluck('semester');
... becomes ...
$sem = DB::table('classroom_mappers')->select('semester')->where('Prof_ID', auth()->user()->PID)->get();

Related

How do I make a notification table that makes eloquent relationships to other tables without making too many "<source>_id" columns

Suppose that I have a Notification Table that gets generated when a new log from another table is generated. Suppose I have 3 different logs with different purpose namely: sms_logs, call_logs, and appointment_logs.
I want to make a relationship to each logs without using sms_logs_id, call_logs_id and appointment_logs_id. Instead, I want to build only two columns, one for the type, and the other for the ID. So for example an sms log is generated with an id of 187, it will also generate a notification log with a notification_id of 187 and a type of "sms".
How will I be able to create that? Thank you!
Nice question.
You have to put only two fields in notifications table. foreign_id and log_type.
Whenever you add a log, you have to set log_type accordingly. Then add this relationship in your Notification model.
public function foreignModel()
{
switch($this->log_type){
case "call_log":
return $this->belongsTo('App\Call', 'foreign_id');
break;
}
}
I didn't tried it, but hope it will work fine.
If you are looking for something more dynamic and less robust than this then I don't think that it exists.

How can I Retrieve only a Row from a table in Laravel

I am new in laravel and i am developing an application that I need to display the persons first and last name upon registering on my system. But I am finding it it hard to achieve this instead my code retrieves all the first and last names from my table if i use the instance $contact =contacts::all();
My table named contact has fields like fname, lname,email,phone, body, updated_at,...
I have tried using the ...all()->pluck() to select only the first name and last name but my views displays everything first and last name from the table. I can do it in my views but i need your help in my controller.
Here is my controller
$contact =contacts::all()->pluck('lname','fname').
Anyone with an idea please
-> contacts::all() --- This will result all the data in contacts model
-> contacts::first() --- This will result only single row. please add a where condition with this for required result.
e.g contacts::where('name','=','abc')->first();
contacts::all() will retrieve every single row. If you want to limit the selection to contacts that only have a certain first/last name, then you'll want to use where and get(), which will only get those particular rows:
$fname = 'John';
$lname = 'Doe';
contacts::where('fname', $fname)->where('lname', $lname)->get();
The two variables, of course, would be populated with whatever you're looking for. You can also pass in a comparison as the second parameter, in case you want to check for not equals, LIKE (good for case insensitive searches or wildcard searches), or greater than/less than for numbers and dates.
contacts::where('fname', '=', $fname)->where('lname','=', $lname)->get();
Note that this will bring up everyone with the name John | Doe. It may not be the person who just registered. For that, you'll want to save the user ID somewhere such as in the session after they register, and instead look for that id, which will bring up only 1 record instead of a collection of records that get() would provide.
contacts::find($id);

Concept of table relations in Laravel

I have two tables:
Cards
Notes
Each Card has multiple Notes. So there is a relation between them like this:
class Card extends Model {
public function notes ()
{
return $this->hasMany(Note::class);
}
}
Ok well, all fine.
Now I need to understand the concept of these two lines:
$card()->$notes()->first();
and
$card()->$notes->first();
What's the difference between them? As you see in the first one $note() is a function and in the second one $note isn't a function. How will they be translated in PHP?
The first one points out to the card table and the second one points out to the notes table, right? or what? Anyway I've stuck to understand the concept of tham.
I don't know about $ before the $notes in your code but if you trying to say something like this.
1- $card->notes()->first();
2- $card->notes->first();
In the code in line 1, first you have a $card model and then you wanted to access all notes() related to that $card, and because of adding () after notes you simply call query builder on notes, show you can perform any other database query function after that, something like where, orderBy, groupBy, ... and any other complicated query on database.
But in the second one you actually get access to a collection of notes related to that $card, we can say that you get all related notes from database and set it into laravel collections and you are no more able to perform database query on notes.
Note: because laravel collections have some methods like where(), groupBy(), whereIn(), sort(), ... you can use them on the second one, but in that case you perform those methods on collections and not database, you already get all results from database

Populate a Select Box with Eagerloading

Any idea what the best way would be to populate a select box with eagerloading?
For example: I can eagerload a hasOne relation like so which works fine for showing the initial status.
Order Model
public function status()
{
return $this->hasOne('OrderStatus','id','status');
}
But then on the order page I also need to populate a select box with all statuses so a user can change the order status.
Order Status Model
public function allStatuses()
{
return OrderStatuses::all();
}
and then I try calling with the dot notation, but that does not work
$order::with('orderStatus','orderStatus.allStatuses')->whereId(1000)->get();
Basically, my views contain a lot of drop-down for things like country, state, etc. I know I can send them through the view with multiple variables, but I would like to just call everything in one collection to the view if possible.
I know the above is probably wrong, but any suggestion on the best way to do this would be appreciated.
Right now I am calling all my common selects from a service provider and then import my repos into that so I can call directly from my view like FormList::getStates(), FormList::getCountries(), etc.. Not sure if this is the best way.

Symfony2/Doctrine - Entity Abstraction in Relation to Normal SQL

I am new to Symfony2 and building an app based on an existing legacy MySQL schema. I've become familiar with all the Intro docs (The Book etc) but still needing to inderstand some higher level concepts of how to properly use the framework. Trying to get my head around the concept of an entity in terms of how I normally would go about writing SQL queries. I've used the CLI to generate entities for all my existing tables. As an example ... there is a Clients and a Titles entity already. Titles are 'owned by' Clients and the core Symfony annotations have mapped them correctly.
So, given a titles table with many columns of values but only one titles.client_id ... say I want to create a form action in the ClientsController (clients.yml route: /clients/{id}/add_title) that for the given client id in the url will allow the user to enter a title name and have it save a new record into titles with only the titles.name & titles.client_id values ... very simple really.
My question is ... in defining this very simple query (in normal SQL)
INSERT INTO (titles) VALUES (name, client_id)
DO I need to create another entity for titles JUST to work with those 2 specific values?
OR
What is the ideal way to use part of an entity for a specific repository ... in this case just a subset of the titles table (name & client_id)?
Here is the Action method in my Clients Controller:
//use Entity & Form namespaces for BOTH tables;
public function addTitleAction(Request $request)
{
$client_entity = new Clients;
$titles_entity = new Titles;
// generate simple 2 input form with Form\TitlesType
return etc ...
}
You may be able to tell, I also need to figure out how to work with the Form classes but my basic question here is how to generate simple queries from larger Entities and how to call from the Controllers of another Entity/Table Controller. Thx for your help.
To wrap your head around the new concepts, think of an entity as a row returned from your table. Think of a repository as your queries on the table. So you should have a Title entity (not Titles).
INSERT INTO (titles) VALUES (name, client_id)
DO I need to create another entity for titles JUST to work with those
2 specific values?
You'll want to create a new object when creating a new record (think of the new object as a new record that you then save), along the lines of:
$title = new Title();
$title->setClient($client);
$em->persist($title);

Categories