How to call two models in the same function using Laravel? - php

I have two functions in my controller, I would like to call the model Tbl_Perimetro and Tbl_Holding, I've achieved to call Tbl_Perimetro.. but I don't know how to call Tbl_Holding to work in the same way of Tbl_Perimetro
these are my functions
public function edit($id)
{
if(request()->ajax())
{
$data = Tbl_Perimetro::findOrFail($id);
return response()->json(['result' => $data]);
}
}
public function update(Request $request, Tbl_Perimetro $user)
{
$rules = array(
'rif' => 'required',
'razon_social' => 'required',
'holdings_id' => 'required',
'pines_id' => 'required'
);
$error = Validator::make($request->all(), $rules);
if($error->fails())
{
return response()->json(['errors' => $error->errors()->all()]);
}
$form_data = array(
'rif' => $request->rif,
'razon_social' => $request->razon_social,
'holdings_id' => $request->holdings_id,
'pines_id' => $request->pines_id
);
Tbl_Perimetro::whereId($request->hidden_id)->update($form_data);
return response()->json(['success' => 'Datos actualizados satisfactoriamente.']);
}

You don't need to use Tbl_Perimetro $user in your update() function's argument.
Instead, include the Models at the beginning of your controller:
use App\Tbl_Perimetro;
use App\Tbl_Holding;
And then you can use those models anywhere in that controller:
Tbl_Perimetro::whereId($request->hidden_id)->update($form_data);
Tbl_Holding::whereId($request->hidden_id)->update($form_data);
Hope it helps.

Do like this:
$data1=tbl_Perimerto::findorfail($id1);
$data2=tbl_Holding::findorfail($id2);
return reponse()->json( ['result1'=>$data1,'result2'=>$data2]);
But what is $id1 and $id2? They was passed from routing:
route::get('/yoururl/{id1}/{id2},['uses'=>'YourController#method']);
and in your controllers method you should get them in arguement like this:
public function method($id1,$id2)

Related

Laravel - adding relationships to a factory-created model

I am testing an eager loading relationship which contains many to many relations. Right now I have the queries and attachments within the test. I'm wondering if there is a way to move them into the factory, rather than including it as part of your test. This would limit the size of the test and then these relations could be created and used every time a film factory is created.
test
public function grabFilmTest()
{
$film = factory(Film::class)->create();
$categories = Category::where('main-cat', 'Science')->where('sub-cat', 'Fiction')->first();
$languages = Languages::where('name', 'english')->first();
$film->categories()->attach($categories->id);
$film->languages()->attach($languages->id);
$response = $this->json('GET', '/film/' . $film->id)
->assertStatus(200);
$response
->assertExactJson([
'id' => $film->id,
'name' => $film->name,
'description' => $film->description,
'categories' => $film->categories->toArray(),
'languages' => $film->languages->toArray()
}
filmFactory
$factory->define(\App\Models\Film::class, function (Faker $faker){
return [
'id' => $faker->uuid,
'name' => $faker->text,
'description' => $faker->paragraph,
];
});
If anyone could help with how i could do this or an example it would be great :D
You could use factory states and factory callbacks.
$factory->define(\App\Models\Film::class, function (Faker $faker){
return [
'id' => $faker->uuid,
'name' => $faker->text,
'description' => $faker->paragraph,
];
});
$factory->define(\App\Models\Category::class, function (Faker $faker){
return [
// Category fields
];
});
$factory->define(\App\Models\Language::class, function (Faker $faker){
return [
// Language fields
];
});
$factory->afterCreatingState(\App\Models\Film::class, 'with-category', function (\App\Models\Film $film) {
$category = factory(\App\Models\Category::class)->create();
$film->categories()->attach($category->id);
});
$factory->afterCreatingState(\App\Models\Film::class, 'with-language', function (\App\Models\Film $film) {
$language = factory(\App\Models\Language::class)->create();
$film->categories()->attach($language->id);
});
Then you can use in tests like this:
public function grabFilmTest()
{
$film = factory(Film::class)->create();
$filmWithCategory = factory(Film::class)->state('with-category')->create();
$filmWithLanguage = factory(Film::class)->state('with-language')->create();
$filmWithCategoryAnLanguage = factory(Film::class)->states(['with-category', 'with-language'])->create();
// ...
}
PS: I don't recommend using existing data. From experience, I can tell you that can become really painful.
You can use factory callbacks to do it in the factory file:
<?php
use \App\Models\Film;
use \App\Models\Category;
use \App\Models\Languages;
$factory->define(Film::class, function(Faker $faker){
return [
'id' => $faker->uuid,
'name' => $faker->text,
'description' => $faker->paragraph,
];
});
$factory->afterCreating(Film::class, function(Film $film, Faker $faker) {
$category = Category::where('main-cat', 'Science')->where('sub-cat', 'Fiction')->first();
$language = Languages::where('name', 'english')->first();
$film->categories()->attach($category);
$film->languages()->attach($language);
});

validate on array parameter igoners my rules and update

I have a function that updates the data. It receives the data as an array parameter.
I tried use validator make, and also validate helper method but it didn't work because it's only work for requests, and i tried also in validator make as the code below and also 'params.name' but it didn't work.
public function updateCompany(array $params): bool
{
if( Validator::make($params,[
'name'=> 'required|min:3|unique:company',
'email'=> 'required|min:4|unique:company|email'
])) {
return $this->update($params);
}
}
After trying this it didn't give me any error put it ignores my validation rules and update anyway.
Just use
public function updateCompany(Request $request)
then you could do something like this:
$rules = array('name' => 'required',
'email' => 'email|required|unique:users',
'name' => 'required|min:6|max:20');
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return ['status' => 422, 'errors' => $validator->errors()];
}

can't access variable in view from controller laravel

I can't access $prospectus in the function show() but works well in the function store() in laravel version 5.6.27
public function store(Request $request) {
$course = Course::create([
'name' => $request['name'],
'title' => $request['title'],
'division_id' => $request['division_id'],
]);
$prospectus = Prospectus::create([
'years' => $request['years'],
'name' => $course->name,
'user_id' => null,
'course_id' => $course->id,
]);
return view('courses.show', compact('course', 'prospectus'));
}
public function show(Course $course) {
$prospectus = Prospectus::where('course_id', $course->id)->get();
//return $prospectus;
return view('courses.show', compact('course', 'prospectus'));
}
the data is passed when i use return $prospectus; but not in return view('courses.show', compact('course', 'prospectus'));
here are my routes
Route::resource('courses', 'CourseController');
Route::post('courses', 'CourseController#store')->name('courses.store');
Route::get('courses/{course}', 'CourseController#show')->name('courses.show');
I supose you want a single Prospectus object, get() will give you a collection of objects.
Use the first() function to get only the first match from the database as a single object.
$prospectus = Prospectus::where('course_id', $course->id)->first();
Confirm that $prospectus query don't return NULL
Try this:
$prospectus = Prospectus::where('course_id', $course->id)->first();

PHP how to stop the code when a called method use return

I have made a main method which calls a validation method to check if everything is correct. But when the validation method find a problem and want to return the error and show it to the user the main method will continue with the rest of the code. How could you prevent this from happening? Here is my current code:
public function postUpdateSettings(Request $request)
{
$this->validateSettings($request);
$this->updateSettings($request);
return redirect()->back()->with('succes', 'Your settings has been changed!');
}
private function validateSettings(Request $request)
{
$this->validate($request, [
'email' => 'required|string|email|max:255|unique:users,email,'.Auth::user()->id.'',
'first_name' => 'required|string|max:50|alpha',
'insertion' => 'nullable|max:25|alpha_spaces',
'last_name' => 'required|string|max:50|alpha',
'job' => 'required',
'message' => 'nullable|max:500',
]);
$jobs = $this->getJob();
if(in_array($request->input('job'), $jobs) === false){
return redirect()->route('home');
}
}

Laravel Fractal transformer, how to pass and get extra variable

I'm using Dingo API to create an API in Laravel 5.2 and have a controller returning data with
return $this->response->paginator($rows, new SymptomTransformer, ['user_id' => $user_id]);
However, I don't know how to retrieve user_id value in the SymptomTransformer! Tried many different ways and tried looking into the class but I'm relatively new to both Laravel and OOP so if anyone can point me to the right direction, it'd be greatly appreciated.
Below is my transformer class.
class SymptomTransformer extends TransformerAbstract
{
public function transform(Symptom $row)
{
// need to get user_id here
return [
'id' => $row->id,
'name' => $row->name,
'next_type' => $next,
'allow' => $allow
];
}
}
You can pass extra parameter to transformer constructor.
class SymptomTransformer extends TransformerAbstract
{
protected $extra;
public function __construct($extra) {
$this->extra = $exta;
}
public function transform(Symptom $row)
{
// need to get user_id here
dd($this->extra);
return [
'id' => $row->id,
'name' => $row->name,
'next_type' => $next,
'allow' => $allow
];
}
}
And call like
return $this->response->paginator($rows, new SymptomTransformer(['user_id' => $user_id]));
You can set extra param via setter.
class SymptomTransformer extends TransformerAbstract
{
public function transform(Symptom $row)
{
// need to get user_id here
dd($this->test_param);
return [
'id' => $row->id,
'name' => $row->name,
'next_type' => $next,
'allow' => $allow
];
}
public function setTestParam($test_param)
{
$this->test_param = $test_param;
}
}
And then:
$symptomTransformer = new SymptomTransformer;
$symptomTransformer->setTestParam('something');
return $this->response->paginator($rows, $symptomTransformer);
If you are using Dependency Injection, then you need to pass params afterwards.
This is my strategy:
<?php
namespace App\Traits;
trait TransformerParams {
private $params;
public function addParam() {
$args = func_get_args();
if(is_array($args[0]))
{
$this->params = $args[0];
} else {
$this->params[$args[0]] = $args[1];
}
}
}
Then you implement the trait in your transformer:
<?php
namespace App\Transformers;
use App\Traits\TransformerParams;
use App\User;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
use TransformerParams;
public function transform(User $user)
{
return array_merge([
'id' => (int) $user->id,
'username' => $user->username,
'email' => $user->email,
'role' => $user->roles[0],
'image' => $user->image
], $this->params); // in real world, you'd not be using array_merge
}
}
So, in your Controller, just do this:
public function index(Request $request, UserTransformer $transformer)
{
$transformer->addParam('has_extra_param', ':D');
// ... rest of the code
}
Basically, the trait is a bag for extra params.

Categories