How to include an association with a user - laravel

I need to return a json object to my view. I see my subscriptions in tinker:
\App\User::find(1)->with('subscriptions')->where('id', 1)->get();
In my view, I get my user data but the subscriptions array is emply (length: 0)
Issue one, why I could not just \App\User::find(1)->with('subscriptions')->get() This returns all users in my database.
How can I return, as json, the current user with subscriptions? The long way is to make two api calls.
Im using Cashier for the subscriptions

Try to check the query log by running
\DB::enableQueryLog();
$data = \App\User::with('subscriptions')->find(1);
$query = \DB::getQueryLog();
dd($query);
It will show you what queries running behind the seens.
then for the json format try to decode into json and then pass to view.
$json_format = json_encode($data);
return view('user.index')->withJsonFormat($json_format);
Don't know why you want to pass the data with json format. but if you want to pass this into javascript, jquery or angular please create saperate API and call with AJAX.

The correct query is:
App\User::with('subscriptions')->find(1)
It will return User object with this user's subscriptions.

Related

Laravel Pagination on POST request

Im using Laravel v7 and i have a question about pagination.
So far im using 2 routes, 1rst to return a view with all rows from database, and 2nd receives an input and returns that view with the rows filtered by that input value.
But im using pagination, and on the 2nd route, when i try to go to 2nd page it gives me an error:
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
The GET method is not supported for this route. Supported methods: POST.
I've tried to change my form method to GET but i need that the token doesn't appear on the page URL and beside that, when i go to 2nd page, it returns all the rows again.
Thats my code so far:
Routes:
Route::get('concessions', 'ConcessionController#index')->name('concessions.index');
Route::post('concessions/search', 'ConcessionController#search')->name('concessions.search');
Controller
class ConcessionController extends Controller
{
public function index()
{
$concessions = DB::table('concessions')->paginate(12);
return view('admin.concessions.index', compact('concessions'));
}
public function search(Request $request)
{
$name = $request->name;
$concessions = Concession::where('name', 'like', '%' . $name . '%')->paginate(12);
return view('admin.concessions.index', compact('concessions', 'name'));
}
}
Any way to do that?
Laravel pagination only works with get parameters.
You should use GET method for your search page. POST requests aren't meant for the purpose of displaying data. Why? There are many reasons, but to be short I will give you three examples :
1. When you access the first page, you get the data by GET request,
not POST request. So if you want to use POST request, you
need to access the page as POST request by sending data with
POST method.
2. With GET parameters, let's say you are on 5th page - you can
copy the link and paste it to friend and he will be able to view
the same content as you. With POST this is impossible.
3. You can not use back button with POST requests, if you manage to
get pagination to work.
POST requests are useful when you need to submit data to the server, in order to create new record, for example.
So I suggest you to change your route type to GET.
From my perspective, if you change your route code similar to below code, it will work properly with both methods of GET and POST.
Route::any('concessions/search', 'ConcessionController#search')->name('concessions.search');

laravel using validation request with except method

I am using request validation as
php artisan make:request ClientRequest
As you can see, on client edit form if password field is not empty I am able to use $request->validated() method on database update,
However if password field empty(user dont want to change password),
I am not able to use $request->except('password')->validated() method.
I use $request->except() method due to this situation.
Does this pose a security problem?
public function update(ClientRequest $request, Client $client)
{
$validated = $request->validated();
if($request->filled('password') )
{
Client::whereId($client->id)->update($validated);
}else{
Client::whereId($client->id)->update($request->except('password'));
}
return redirect('/clients')->with('success', 'success');
}
Client::whereId($client->id)->update($request->except('password'));
That line is does pose a big security problem especially if you are relying on validation to set fields rather than the fillable attribute. $request->except('password') will return all the other fields that the user submitted so if the user had added something like is_admin => true in the request, you'll end up setting it on the db if it exists.
You can use \Illuminate\Support\Arr::except() on the validated data to make sure that you are only getting the data you expect. That would change the that particular line to
Client::whereId($client->id)->update(\Illuminate\Support\Arr::except($request->validated(), 'password'));
PS: You already have the client through route model binding so you don't need to query it you can update that client directly i.e
$client->update(\Illuminate\Support\Arr::except($request->validated(), 'password'));
You are validating all fields sent to update() in both scenarios.
You would have had an issue if you sent the password field in both cases, but only validated it in one of them. That's not the case.
So looks fine to me from that perspective.

API request with multiple body inputs

I am new to laravel this is how I make an API with one single body item
$shops_categories=ShopsCategories::all()->where('title',$request->title);
how to request more than an item in the body for example title , email , password ?
Eloquent allows you to chain as many where as required. So you are able to do
$shops_categories = ShopsCategories::where('title',$request->title)->where('email',$request->email)->where('password',$request->email)->get();
You can do it like so:
$cats = ShopsCategories::query()->where(['title' => $title, 'email'=>$email, 'name'=>$name]);
i guess you are performing query operation in controller itself which is not recommended,please create an instance for the model and make a function call to model and in the model you can return like
return $this::where('id','=',$id)->get()
and also please try to avoid using text/string in where condition instead use id's or unique values
You can also convert request to array using all()
//$request->all() is same as ['title'=> 'my title', ...]
$shops_categories=ShopsCategories::where($request->all())->get();

Laravel if statement for request object

Currently building out an API. I am working on an update function with excepts the incoming request. so: api.dev.com/?api_key=asdf&storeid=2 etc
now in the backend i am accepting the Request and then i am trying to write some logic to check if the request includes storeid then update that entry etc.
But when i am writing my logic and i do
if(isset($request->storeid))
$store->id = $request->storeid;
If I do not include storeid in my put request then i get:
Call to a member function parameter() on a non-object
Because it is not present. Am I approaching writing this logic the wrong way?
I want to leave it up to the users to update the records they want. So they should not have to include all the variables in the request. Just those that need to be updated.
Citti
Do this instead:
if($request->has('storeid')) {
...
The error "Call to a member function parameter() on a non-object" is not because you are not including the "storeid" input, but because you are not calling an instance of the Store object.
Maybe if you do something like:
if(isset($request->storeid))
$store = Store::findOrFail($request->storeid)

symfony2 controller needs two ways of return-values, one for symfony-application (inside symfony) one for mobile (json)

I'm trying to build a restful JSON api for my Symfony2 Application.
I'm using the http://jmsyst.com/libs/serializer JMS\Serializer Bundle to serialize my Entities to JSON.
I have this example Controller-Action:
public function getFarmerByNameAction(Request $request) {
$this->setLocale($request);
$name = $request->get("name");
$farmer = $this->getDoctrine()->getRepository("FarmerguideBackendBundle:Farmer")->findByName($name);
// Return json response
return new Response($this->jsonify($farmer));
}
Since I'm using this serializer very often (I know I should do something like a singleton or whatever, but currently I don't have the time for that, I was just playing with the framework) I've put the code inside a function which does the serializing.
private function jsonify($object) {
// Serialize to json
$serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new
JsonEncoder()));
$json = $serializer->serialize($object, 'json');
return $json;
}
My problem is the following:
This code is inside a BackendController, which does NOT contain any gui-specific information. So just a RESTful API.
In another Controller, let's say WebappController I have the code to access these backendfunctions and do some stuff with twig-files and render()-methods.
I want to access all these information via mobile over ajax (therefore I need this json return value)
What's the best-practice here? Is it better to say: Well if it's a ajax-call (check with if($request->isXmlHttpRequest())) , do jsonify right before returning the repsonse and if it's not return the entities (I need entities for twig-templates..) Or is there another approach?
Or is it even better to work with $request->getFormatType() and making the ajax call with contentType="application/json; charset=utf-8"
Here is how KnpBundles handles it https://github.com/KnpLabs/KnpBundles/blob/master/src/Knp/Bundle/KnpBundlesBundle/Controller/DeveloperController.php#L35
I guess you need to clearify what your intentions are. Because right now it seems as if your WebappController would just be a client to your Backendcontroller. Something like:
$result = file_get_contents('/path/to/backend/method/1/3');
You then simply go ahead and decode the json.
That is some additional overhead of course. If you want to get entities, I would suggest to create a Service for all your backend methods and return the entities there. You then simply call those methods from your BackendController and your WebappController. You then would only jsonify the entities in your BackendController and render the appropriate templates in your WebappController.

Resources