I need laravel to return all object attributes upon saving including null attributes - json

I have a model instance for which I set the attributes from a post request using $my_instance->fill($request_json) and after saving using $my_instance->save() the instance as a record in the database, I want to receive the saved object back with all its attributes using return response()->json($my_instance). Now this works fine as long as I provide all the attributes I set in the protected $fillable = [] on the model class inside the post request body. But when I want to send only part of the attributes in the post request, what happens is that inside tinker I see the skipped attributes are set to null. This is fine. But the problem is when I return using return response()->json($my_instance) I don't see the skipped attributes and I want them to be returned even with them being null in my databse. Is there a way to instruct laravel to do so?

A possible implementation to your question COULD be to:
Allow all possible fields that are getting nulled out to be fillable in your model.
Then, use a middleware with collections to do:
$form_stuff = $request->all();
$form_stuff = collect($form_stuff);
$things_you_want = $form_stuff->only('wanted_field_1','wanted_field_2');
$things_that_should_be_null = $form_stuff->only('nulled_field_1','nulled_field_2');
$keys = array_keys($thins_that_should_be_null);
$values = array_fill(0, count($keys), null);
$new_array_of_nulled_things = array_combine($keys, $values);
var_dump($things_you_want);
var_dump($new_array_of_nulled_things);
die();
WARNING: Since there was no code posted, this is just concept mostly and has not been tested so you will have to play with it to get it work the way you want.

Related

Laravel 5.4 formatting result set

Can someone help me convert this query so that my result set is in different format?
$sessions = new Session();
$results = $sessions->where('session_status', $status)->where('application_period_id', (int) ApplicationPeriod::all()->last()->id)->get()->pluck('speaker_id');
$speakers = Speaker::whereIn('id', $results)
->with('session.audiancesession.audiances')
->with('session.subjectsession.subjects')
->with(['session' =>
function ($query) use($status) {
$query->where('session_status', '=', $status);
}])->orderBy('last_name')->get();
This is requested via Ajax(axios)... Now this is how result is formatted:
Obj->data(array of objects)->[0]->name
->address
->session(array of objects)
->[0]->time
->fee
My issue is that my session parameter is array and there can only ever be (1) so I don't need to to be an array and I would like to have object (json) instead.
Thank you!
You might have more success if you change your client-side code to work with an array of sessions each session having its speaker, that means your original query would be like
$sessions = Sessions::with([
'speaker', 'audiancesession.audiances', 'subjectsession.subjects'
])->where('application_period_id', (int) ApplicationPeriod::orderBy('id','DESC')->first())->get();
Note the order by -> first in the ApplicationPeriod makes it so you don't have to get all application periods from the database to memory.
Then your client side should handle an array of sessions.
You can transform the above slightly using to get a similar result to what you need:
$speakers = $sessions->map(function ($session) {
$speaker = collect($session->speaker->toArray());
$speaker->put('session', collect($session->toArray())->except('speaker'));
return $speaker;
})->orderBy('last_name','DESC');
Though I wouldn't guarantee the result here as I've not tested it on your (complex looking) data.

insert query symfony 2 without form

I'm working with Symfony 2 and I need to insert some data in a MySQL table. I know how to do it using a form:
$m=new table();
$form=$this->container->get('form.factory')->create(new tableType(),$m);
$request=$this->getRequest();
if($request->getMethod()=='POST')
{
$form->bind($request);
if ($form->isValid())
{
$rm=$this->container->get('doctrine')->getEntityManager();
$rm->persist($m);
$rm->flush();
}
that works but I dont want to use a pre-defined form because I need complex control on my input. I need to generate the value with jQuery.
So how can I proceed to insert the values of my input into my table?
Generally you can pass the whole request to the action as following
use Symfony\Component\HttpFoundation\Request;
// <...>
public function fooAction(Request $request)
{
$foo = $request->query->get('foo', 'default_value_for_foo'); // get the foo param from request query string (GET params)
$bar = $request->query->get('bar', 'default_value_for_bar'); // get the bar param from request POST params
}
Also you might be interested in collection form types which can allow you to generate multiple rows or entities for form (not fixed)
That's actually easier than using forms :D
<?php
// ...
// fetch your params
$m = new table();
$m->setWhatever($request->get('whatever'));
// persist
$em = $this->get('doctrine.orm.entity_manager');
$em->persist($m);
Note:
use camel-case PHP-class names: e.g. Table, NiceTable
$form->bind is deprecated I think, use $form->handleRequest
anyway if you need to validate your input, I recommend using validators and forms anyway. Setting up a model and validate it is quite smart. You don't need to create the view createView() of it of course, but the validation component in Symfony is very mighty :).

Codeigniter -> 2 variables inside a controller

I am trying to set up a filter on my website. Here, I am trying to pass (2) variables (neighborhood and business category). My problem is when only (1) of them is true and the other is false or one variable does not exist. I am trying to pull this data from my URL
mydomain.com/controller/function/neighbrohood/biz-category
which translates
mydomain.com/ny/find/$neighborhood/$biz_filter
When I have both variables then there is no problem.
How do I resolve the page with only 1 of the 2 variables there?
Here is my model:
public function search($neighborhood = null, $biz_filter = null) {
$neighborhood = $this->uri->segment(3);
$biz_filter = $this->uri->segment(4);
// SELECT
$this->db->select('*');
// MAIN TABLE TO GRAB DATA
$this->db->from('biz');
// TABLES TO JOIN
$this->db->join('city', 'city.city_id = biz.biz_cityID');
$this->db->join('zip', 'zip.zip_id = biz.biz_zipID', 'zip.zip_cityID = city.city_id');
$this->db->join('state', 'state.state_id = city.city_stateID');
$this->db->join('neighborhood', 'biz.biz_neighborhoodID = neighborhood.neighborhood_id');
$this->db->join('biz_filter', 'biz_filter.bizfilter_bizID = biz.biz_id');
$this->db->join('biz_category', 'biz_filter.bizfilter_bizcategoryID = biz_category.bizcategory_id');
// RETURN VARIABLES
$this->db->where('neighborhood.neighborhood_slug', $neighborhood);
$this->db->where('biz_category.bizcategory_slug', $biz_filter);
// ORDER OF THE RESULTS
$this->db->order_by('biz_name asc');
// RUN QUERY
$query = $this->db->get();
// IF MORE THAN 0 ROWS ELSE DISPLAY 404 ERROR PAGE
if($query->num_rows() > 0){
return $query;
} else {
show_404('page');
}
}
Example. Say I am looking for a Restaurant in Little Italy:
URL = mydomain.com/ny/find/little-italy/restuarants
This part, I can resolve the query correctly and display the data. The issue is when there is no neighborhood or no category, I cannot figure out how to resolve the data.
I am new to codeigniter and a self-taught programmer, trying to figure this out as I go. Any help would be much appreciated.
Thank you in advance.
first of all it is optional to get the variables from the uri
$neighborhood = $this->uri->segment(3);
$biz_filter = $this->uri->segment(4);
You already have that from your function parameter.
You can check the condition where your $neighborhood or $biz_filter is available or not then you can use condition in your query.
Something like this
if($neighborhood) { // query for neighborhood } elseif($biz_filter) {}
Thanks
First of all you should get the variable values from your controller not your model, you should then pass such values to your controller from your model, its bad coding practice to allow your view interact with the model.
Also, if you want a value of "-" set for the variable. You should set "-" as the return value right from the parameters being passed to the controller.
What you should do is go to your controller and give it the two parameters, set default values for both and also go to your model and make it receive two parameters also, pass the parameters to the model when calling from the controller. Then get back if there are any more errors.

Play + Slick: How to do partial model updates?

I am using Play 2.2.x with Slick 2.0 (with MYSQL backend) to write a REST API. I have a User model with bunch of fields like age, name, gender etc. I want to create a route PATCH /users/:id which takes in partial user object (i.e. a subset of the fields of a full user model) in the body and updates the user's info. I am confused how I can achieve this:
How do I use PATCH verb in Play 2.2.x?
What is a generic way to parse the partial user object into an update query to execute in Slick 2.0?I am expecting to execute a single SQL statement e.g. update users set age=?, dob=? where id=?
Disclaimer: I haven't used Slick, so am just going by their documentation about Plain SQL Queries for this.
To answer your first question:
PATCH is just-another HTTP verb in your routes file, so for your example:
PATCH /users/:id controllers.UserController.patchById(id)
Your UserController could then be something like this:
val possibleUserFields = Seq("firstName", "middleName", "lastName", "age")
def patchById(id:String) = Action(parse.json) { request =>
def addClause(fieldName:String) = {
(request.body \ fieldName).asOpt[String].map { fieldValue =>
s"$fieldName=$fieldValue"
}
}
val clauses = possibleUserFields.flatMap ( addClause )
val updateStatement = "update users set " + clauses.mkString(",") + s" where id = $id"
// TODO: Actually make the Slick call, possibly using the 'sqlu' interpolator (see docs)
Ok(s"$updateStatement")
}
What this does:
Defines the list of JSON field names that might be present in the PATCH JSON
Defines an Action that will parse the incoming body as JSON
Iterates over all of the possible field names, testing whether they exist in the incoming JSON
If so, adds a clause of the form fieldname=<newValue> to a list
Builds an SQL update statement, comma-separating each of these clauses as required
I don't know if this is generic enough for you, there's probably a way to get the field names (i.e. the Slick column names) out of Slick, but like I said, I'm not even a Slick user, let alone an expert :-)

Grails: can I make a validator apply to create only (not update/edit)

I have a domain class that needs to have a date after the day it is created in one of its fields.
class myClass {
Date startDate
String iAmGonnaChangeThisInSeveralDays
static constraints = {
iAmGonnaChangeThisInSeveralDays(nullable:true)
startDate(validator:{
def now = new Date()
def roundedDay = DateUtils.round(now, Calendar.DATE)
def checkAgainst
if(roundedDay>now){
Calendar cal = Calendar.getInstance();
cal.setTime(roundedDay);
cal.add(Calendar.DAY_OF_YEAR, -1); // <--
checkAgainst = cal.getTime();
}
else checkAgainst = roundedDay
return (it >= checkAgainst)
})
}
}
So several days later when I change only the string and call save the save fails because the validator is rechecking the date and it is now in the past. Can I set the validator to fire only on create, or is there some way I can change it to detect if we are creating or editing/updating?
#Rob H
I am not entirely sure how to use your answer. I have the following code causing this error:
myInstance.iAmGonnaChangeThisInSeveralDays = "nachos"
myInstance.save()
if(myInstance.hasErrors()){
println "This keeps happening because of the stupid date problem"
}
You can check if the id is set as an indicator of whether it's a new non-persistent instance or an existing persistent instance:
startDate(validator:{ date, obj ->
if (obj.id) {
// don't check existing instances
return
}
def now = new Date()
...
}
One option might be to specify which properties you want to be validated. From the documentation:
The validate method accepts an
optional List argument which may
contain the names of the properties
that should be validated. When a List
is passed to the validate method, only
the properties defined in the List
will be validated.
Example:
// when saving for the first time:
myInstance.startDate = new Date()
if(myInstance.validate() && myInstance.save()) { ... }
// when updating later
myInstance.iAmGonnaChangeThisInSeveralDays = 'New Value'
myInstance.validate(['iAmGonnaChangeThisInSeveralDays'])
if(myInstance.hasErrors() || !myInstance.save(validate: false)) {
// handle errors
} else {
// handle success
}
This feels a bit hacky, since you're bypassing some built-in Grails goodness. You'll want to be cautious that you aren't bypassing any necessary validation on the domain that would normally happen if you were to just call save(). I'd be interested in seeing others' solutions if there are more elegant ones.
Note: I really don't recommend using save(validate: false) if you can avoid it. It's bound to cause some unforeseen negative consequence down the road unless you're very careful about how you use it. If you can find an alternative, by all means use it instead.