Laravel calling model with variable in controller - php

I am using one function in controller for inserting in several different tables with different Models. I mean that in controller model is variable.
This code bellow works perfectly but i don't like syntax, i am pretty sure there must be some other ways than str_replace for calling model with \App\ in front of it's name.
Calling only by Model name without \App\ causes laravel error Class not found. I have written use \App\ModelName in controller's file but it still does't works.
public function storeCommon(Request $request){
$model = '"\App\"'. $request->model;
$model = str_replace ( "\"", "", $model ) ;
........
........
$row['text'] = $request->text;
........
........
$common = $model::create($row);
}

I would rather define array of possible models and use it within the code. This way you will protect your code against call for unwanted models and off course your code will be much readable:
protected $possibleModels = [
'Model1' => \App\Model1::class,
'Model2' => \App\Model2::class,
...
];
public function storeCommon(Request $request){
if (!isset($this->possibleModels[$request->model])) {
abort(404);
}
$model = $this->possibleModels[$request->model];
$row['text'] = $request->text;
...
$common = $model::create($row);
}

Related

Laravel import model in function

I'm trying to import the model in function and call create function of the specific model.
I know which model to call from Route::currentRoute();, so it must look like
$model = Route::currentRouteName() // return like 'Blog/Post'
$create = new App\Models\$model::create($request->input());
Any ideas on how to do it in that way?
You must put the full model path into the string, then it will work.
Also make sure that you replace forward slashes with backslashes.
And if you use 'create' you don't need 'new'.
Here the final result:
$model = str('Blog/Post')->replace('/', '\\');
$fullPath = 'App\Models\\' . $model;
$create = $fullPath::create($request->input()]);
We can just use call it putting a full path of the model. for eg:
public function callModel(Request $request){
$create = App\Models\$model::create($request->input());
dd($create);
}

Import Model via Ajax Request Laravel - without namespacing the model

I am trying to import a model via an Ajax request without namespacing the model.
public function dataTypeRender(Request $request)
{
$input = request()->all();
$model = $request->input('model'); //this is the model name
$cols = $request->input('cols');
$modelTest = $model::all(); //not working
dd($modelTest);
}
Is there a way to do this? I'm trying to then do something with the model data.
I think without namespace it gonna be a little harder, because your model could be any model, but i think this could help you.
public function example(Request $request){
$data = $request->all(); //get All data request
$namespace = 'App\\'; //set namespace
$modelWithNameSpace = $namespace.$data['model']; //concat namespace and model name
$model = str_replace("'", "", $modelWithNameSpace); //remove quotes (idk if it's the best approach)
return $model::all(); //return the modell with all
}
This seemed to work nicely.
$model = 'App\\' . $request('model'); // adjust for the namespace/folder where you put your models
$data = (new $model)->all();
or
$data = (new $model)->find(1);

How to access virtual field in controller instead of model entity in cakephp 3.2

I have implemented virtual filed in model/entity/Order.php .
But i want to access for one page only ,i don't want it to be called for all the functions .So in controller how can i access virtual field so that it will be applicable for only the portion i need.
In cakephp 2x version ,i have made for controller ,but this time in 3X i am unable to make it.
below i have attached some codes
Any suggestion will be appreciated.
Thank you .
Model/Entity/Order.php
protected $_virtual = ['amount'];
protected function _getAmount() {
$data = [];
$data['due'] = $this->_properties['collection']['due_amount'];
$data['paid'] = $this->_properties['collection']['total_sale_amount'] - $this->_properties['collection']['due_amount'];
return $data;
}
Codes in controller
$Lists = $this->Orders->find('all')->where($condition)->contain(['Collections','Customers'=> ['queryBuilder' => function ($q) {
return $q->select(['id','center_name']);
}],])->order(['Orders.due_date ASC']);
You have used getter method of entity by declaring function _get*. Your getter method name is _getAmount(), so you can access this by entity object in controller $entity->amount();
$Lists = $this->Orders->find('all')->where($condition)->contain(['Collections','Customers'=> ['queryBuilder' => function ($q) {
return $q->select(['id','center_name']);
}],])->order(['Orders.due_date ASC']);
// Iteration will execute the query.
foreach ($Lists as $entity) {
echo $entity->amount;
}
Check document about virtual field in CakePHP 3.x
Also no need of below line in Entity, so remove it, because you are using getter method.
protected $_virtual = ['amount'];

Laravel 5.2 - creating a model from a variable

I am trying to access dynamically models so that I can get the count for each of them depending on which string I pass to the function.
This is what my function in the controller looks like:
public function numberOf(Request $request){
$modelName = $request['option'];
$model = new $modelName;
$data = $model->count();
return json_encode($data);
}
But when I pass a string, like in this case 'Article' I get an error:
Fatal error: Class 'Article' not found
Even though I am calling it in the controller:
use App\Article;
I had to add App to model name, so that my function looks like this now and everything works fine now:
$modelName = 'App\\'.$request['option'];
$model = new $modelName;
$data = $model->count();
return json_encode($data);

How to save database operation in laravel

Thanks for watching my first question.
I have something confused.
How could I write the operations of database into database and don't write the function in every Controller?
I have considered middleware and find that must change my route register style.
my Route is this:
Route:resource('province','\\Modules\\Info\\Controllers\\P_ProvinceController');
Dose it has some awesome methods replace this?
public function Store(Request $request)
{
$params = $request->input('data');
$params['CreateID'] = Auth::user()->id;
$params['CreateName'] = Auth::user()->name;
$params['CreateTime'] = Carbon::now();
$province = P_ProvinceModel::Create($params);
$params['Pro_Is_Del'] = 1;
$log_info['table'] = $province->getTable();
$log_info['type'] = "create";
$log_info['user'] = Auth::user()->name;
$log_info['datetime'] = Carbon::now();
LogModel::create($log_info);
if($province){
return response()->json(array(
'status' => 200,
'msg' => '新增成功',
'data' => $province
));
}else
return response()->json(array(
'status' => 500,
'msg' => '保存失败',
));
}
Thanks.
Here is how I solved across model functionality
First Create a Trait that does what you want on save.
<?php
namespace App\Models\Observers;
trait CreatedByObserver
{
public static function bootCreatedByObserver(){
/** Simply means that whenever this model is creating a model do: */
static::creating(function($model){
if(auth()->check()){
$responsiblePerson = auth()->user()->first_name . " " . auth()->user()->last_name;
} else {
$responsiblePerson = "system";
}
/** You can set any model variables within */
$model->created_by = $responsiblePerson;
});
}
}
In there do all you need to do when a record is saved/created/updated/deleted
Then In all Models you want this behaviour used add the trait.
Check them out here : https://laravel.com/docs/5.2/eloquent#events
As far i understand your question, you are asking for way to make your controller an abstract type, i.e. controller just need to handle the route and view not any other things(like database,application logic etc) which is the philosophy of the laravel Framework.
To make your controller abstract (meaning of abstract as explained aboave),
first you need to understand, "What your application logic are and what your database logic are ?"
when you understand these two things then, you can easily separate your aapplication logic and databasse logic from your controller.
For example :
For keeping your Application logic you can make service folder in your root of your project also you can make folder name 'Dao' (Database access object) in the same path of service . You need to keep these folder in autoload from your composer. Just make class for service and your Dao.
And now your application follow will be,
First Route, will hit controller then controller will need to call some method in service and then service will call the respective DAO . method.
Example :
Controller/YourController.php
Class YourController extends Controller {
public function Store(Request $request,yourservice,$yourService)
{
$this->myservice = $yourservice;
$this->myservice->store('your inputs request');
return $something ;
}
}
service/yourService.php
Class yourService {
public function store($yourinputs,yourDao $mydao){
$this->mydao = $mydao;
//you can use your application logic here
return $this->mydao->create($yourinputs);
}
And now the turn is for DAO :
dao/yourdao.php
use model // use your model here .
class yourDao {
public function create($yourdata,yourmodel $model){
$this->model = $model;
return $this->model->create($yourdata);
}
}
Now, you can see the controller just save the data in database, but don't know how it is saving the data and what are the application logic.
This explanation is just a simple way of doing project to make a controller abstract. There are other various ways of doing this. For example you can see Repository Design Pattern , which also used by laravel core .
Hope this explanation will not bore anyone . :) Happy coding .

Categories