handling models in laravel 5 like in codeigniter - codeigniter

I'm new on laravel.
I have functions on my model php. I want to use them in controller and send to view.
This is my example function.
public function select()
{
$users = DB::table('user')->get();
}
now I need to use this on controller and view.
In codeigniter I handle it like this:
$data['content'] = $this->model->select();
$this->load->view('admin/users', $data);
in codeigniter we first load model then we call its one of its method and then we pass processed data to view . what is counter part of this in laravel 5

In Laravel 5 you can do it only using controller, like this:
public function select()
{
$users = DB::table('user')->get();
return view('admin.users',compact('users'));
}
if you want do it using Eloquent Model you need a model first. I assume you model name is User and your table name is users
User.php
protected $table = 'users'; // mention the table name
UserController.PHP
public function select()
{
$users = User::all(); // it will return a collection of data form User model
return view('admin.users',compact('users')); // write all variables you want pass through inside compact separated with comma
}

Related

Getting the database data to front view in laravel?

As it is quite easy to get data from database in admin panel,but the case is that how can i get/view those data to front view , front view contains the data from several table. Could you please help me ? How can i manage those front pages easily ?
There are a lot of ways, but this is what I normally do.
Use a separate controller method (say index() HomeController) for the frontpage, and create an array of all the variables with the data from database and pass it on to the page. Let's say our homepage has some slider images, some blog posts, and and our team section, then your HomeController would look something like this:
class HomeController extends Controller
{
public function index()
{
$data = []; //your empty array
$data['sliders'] = Slider::all(); //data from sliders table
$data['posts'] = Post::all(); //data from posts table
$data['teams'] = Team::all(); //data from teams table
return view('frontend.index',compact('data'));
}
Now you can access all these in your frontend blade (here index.blade.php) as such:
#foreach($data['teams'] as $key=> $value)
//your loop code
#endforeach
Hope this helps.
In the wonderfull world of laravel this is super easy. But first let me dive a into the structure of laravel a bit.
It all begins with the controller. In Laravel, Controllers a re meant to group assiociated request handling logic within a single class. A basic resource controller would look like this:
class DomainController extends Controller
{
public function index(){} // list domains
public function create(){} // show create form
public function store(Request $request){ } // handle the form POST
public function show($id){} // show a single domain
public function edit($id){} // show edit page
public function update(Request $request, $id){} // handle show edit page POST
public function destroy($id){} // delete a domain
}
Now how can you return the data to the view?
Let's say we want to generate a list of all users using the index function from the controller.
public function index()
{
$users = User::all();
return view('users.index', compact('users'));
}
With this return statement we will get a view and in that view we will have the $users variable available because of the use of the comapct function.
Now if we want to show a simple list:
#foreach($users as $user)
<li>{{$user->name}}</li>
<li>{{$user->age}}</li>
#endforeach

Using an Eloquent relationship within an Eloquent accessor?

I am writing a Laravel application that manages training courses.
Each course is represented by a Course model.
A course can have many dates - these are represented by a CourseDate model, with a hasMany relationship between the two:
Each course also has a single "date template", which is a CourseDate, but with an "is_template" boolean set.
I want to create an accessor on the Course model that retrieves its date template.
The (relevant) code for each model is:
class Course extends Model {
public function getDateTemplateAttribute() {
$dates = $this->dates;
$filtered = $dates->where('is_template', true);
$template = $filtered->first();
return $template;
}
public function dates() {
$result = $this->hasMany( CourseDate::class );
return $result;
}
}
class CourseDate extends Model {
public function course() {
return $this->belongsTo( Course::class );
}
}
Then, in my controller, I have this:
// this block works absolutely perfectly
$course = Course::find(1);
$dates = $course->dates;
$working_date_template = $dates->where('is_template', true)->first();
// this one doesn't work at all and says "call to a member function first() on array"
$broken_date_template = $course->date_template;
Stepping through with xdebug in the broken code, the line $dates = $this->dates returns an empty array so everything else afterwards breaks.
Is this a limitation with the Laravel accessor/relationship system? Or am I just being dense and doing something wrong.
I worked this out just now.
I needed to use $this->dates() within the model itself as this returns the relationship and I can then filter it out accordingly using the where() method and other query builder methods.
This was, of course, mentioned in the Laravel documentation - I just didn't spot it.

Custom method not work on HasMany relation

I trying to call a custom method from a model by relation.
User Model:
class User extends Model
{
public function files()
{
return $this->hasMany(Files::class, 'file_id', 'id');
}
}
File Model:
class Files extends Model
{
public function cover()
{
dd('blah blah');
}
}
In my controller I said:
$user = User::find(1);
$user->files()->cover();
But I will get this error:
Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany::cover()
What is the problem in my code?
Basically you are calling your cover() method over the collection. That's why that is not working.
You are using hasMany Laravel relationship. And this hasMany returns collection of related records(items). And yo can't call any model function on that directly.
But if you wan to call function on this. you need to firstly loop the items, like below example:-
$user = User::find(1);
foreach($user->files() as $file) {
$file->cover();
}
Above code will provide you output. Try this.
If you want to get all the covers of you files, you can do this :
$user = User::with('files.cover')->find(1);
$covers = $user->files->pluck('cover')->flatten();
I want to use this method to check and then store the cover. because I need to check the cover before insert I couldn't use create method, it will be an alias to create. so I couldn't overwrite to create method?
From this, you can do the following:
foreach($user->files as $file){
$cover = $file->cover()->firstOrCreate(['attribute' => $value]);
// If you want to check if you just created the cover
if($cover->wasRecentlyCreated){
// Do stuff
}
}

Laravel 5 - Inserting all POST data into database?

I'm using Laravel 5 and I created a resource controller, setup routing and setup my database model.
My question is: when I do a POST, my store method is called on the controller but how can I take the request data and insert a new entry in the db without having to explicitly set every field?
Here's my code:
public function store(Request $request)
{
$data = $request->all(); // this grabs all my request data - great!
$user = new User;
$user-> ??? // insert ALL posted data
$user->save();
}
I understand that I can do...
$user->name = $request->name;
...for every field. But can someone tell me how to insert everything?
I realize I can probably do a foreach but I'm wondering if there's something better.
There is method fill in every model https://laravel.com/api/5.3/Illuminate/Database/Eloquent/Model.html#method_fill:
$user->fill($request->all());
Eventually you can use create:
\User::create($request->all());
This above is called mass asignment and there is section about this in Eloquents documentation https://laravel.com/docs/5.1/eloquent
You need to define which keys might be set:
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
// The attributes that are mass assignable
protected $fillable = ['name', 'login', 'birthdate'];
}

How to use a protected property in an Eloquent model without Laravel trying to save it to the database

In one of my models, I have an attribute named "slug". When the slug is changed, I need to record the original slug before updating it to the new one, so my model has a protected property "originalSlug". Before saving the model, I do something like this in my model:
protected $originalSlug;
public function customSave($newSlug){
$this->originalSlug = $this->slug;
$this->slug = $newSlug;
return $this->save();
}
Then I have an event that does other tasks using that originalSlug after a successful save.
The problem is Laravel is trying to save the originalSlug to the database though it isn't actually an attribute and doesn't have a database column. So it fails with the "Column not found" error.
What could I do to get Laravel to ignore that originalSlug property, or is there a better way I should be doing this?
If you want Eloquent to ignore a property, it needs to be accessible to set, otherwise __set will be called and Eloquent will treat it as an attribute.
You can alternatively use mutator for this.
So here's what you need:
public $originalSlug;
public function customSave($newSlug){
$this->originalSlug = $this->slug;
$this->slug = $newSlug;
return $this->save();
}
or:
protected $originalSlug;
public function customSave($newSlug){
$this->originalSlug = $this->slug;
$this->slug = $newSlug;
return $this->save();
}
public function setOriginalSlugAttribute($value)
{
$this->originalSlug = $value;
}
Then Eloquent will not set an originalSlug attribute , so it won't be saved to the db.
You can do that with events, like suggested in the comments, and I would suggest this way too.

Resources