How to update nested redux state - react-redux

I have the following structure
lookups --> Object
lookups.CATEGORIES --> array of category objects
lookups.TIMEZONES --> array of timezone objects
I would like to add new object, which is a lookup object which has lookup_type property. It could be either 'CATEGORY' or 'TIMEZONE'.
Depending on lookup_type, the newly added object has to be added either to CATEGORIES or TIMEZONES object. How this could be achieved?
The structure of lookups object
lookups: {CATEGORIES:[{obj1}, {obj2}...], TIMEZONES:[{obj1}, {obj2}, {obj3}...]}

You can use spread on the nested object or array too:
return {
...state,
[action.lookupType]: [
...state[action.lookupType],
action.value,
]
};
That would add a new item to Categories or Timezone, if you want to replace a value or insert it at an index etc then you should construct the new array how you want it just above the return and pass that instead. Also note that array spread is ES7.

You probably want to pass your lookup object as the payload of an action, which your lookup reducer handles. In the lookup reducer check for the value action.payload.lookup_type and return the state with a new CATEGORIES or TIMEZONES array containing the old values of that array with the lookup object insterted. You should probably check out some redux examples first, if you are unsure how to work with it.

Related

How to change gorm.Record type to array

currently I am using gorm to retrieve data from db (postgresql db to be specific) and scan it in an array, the data stored in db is also in form of array. So problem I am facing is after scanning data in empty int array it changes into gorm.Record type which can't be used for basic array operation like, appending, iterating, etc.
Here's a related part of my code:
var winner_selection []int64 // empty int64 array
db.Table("giveaways").Select("Participants").Where("Name = ?", name).Scan(&winner_selection) // scanning the value in array
How can I retrieve the data directly in form of array so the array remains array or is there anyway to change gorm.Record type to array?

SOLVED: Looking for a smarter way to sync and order entries in Laravel/Eloquent pivot table

In my Laravel 5.1 app, I have classes Page (models a webpage) and Media (models an image). A Page contains a collection of Media objects and this relationship is maintained in a "media_page" pivot table. The pivot table has columns for page_id, media_id and sort_order.
A utility form on the site allows an Admin to manually associate one or more Media items to a Page and specify the order in which the Media items render in the view. When the form submits, the Controller receives a sorted list of media ids. The association is saved in the Controller store() and update() methods as follows:
[STORE] $page->media()->attach($mediaIds);
[UPDATE] $page->media()->sync($mediaIds);
This works fine but doesn't allow me to save the sort_order specified in the mediaIds request param. As such, Media items are always returned to the view in the order in which they appear in the database, regardless of how the Admin manually ordered them. I know how to attach extra data for the pivot table when saving a single record, but don't know how to do this (or if it's even possible) when passing an array to attach() or sync(), as shown above.
The only ways I can see to do it are:
loop over the array, calling attach() once for each entry and passing along the current counter index as sort_order.
first detach() all associations and then pass mediaIds array to attach() or sync(). A side benefit would be that it eliminates the need for a sort_order column at all.
I'm hoping there is an easier solution that requires fewer trips to the database. Or am I just overthinking it and, in reality, doing the loop myself is really no different than letting Laravel do it further down the line when it receives the array?
[SOLUTION] I got it working by reshaping the array as follows. It explodes the comma-delimited 'mediaIds' request param and loops over the resulting array, assigning each media id as the key in the $mediaIds array, setting the sort_order value equal to the key's position within the array.
$rawMediaIds = explode(',', request('mediaIds'));
foreach($rawMediaIds as $mediaId) {
$mediaIds[$mediaId] = ['sort_order' => array_search($mediaId, $rawMediaIds)];
}
And then sorted by sort_order when retrieving the Page's associated media:
public function media() {
return $this->belongsToMany(Media::class)->orderBy('sort_order', 'asc');
}
You can add data to the pivot table while attaching or syncing, like so:
$mediaIds = [
1 => ['sort_order' => 'order_for_1'],
3 => ['sort_order' => 'order_for_3']
];
//[STORE]
$page->media()->attach($mediaIds;
//[UPDATE]
$page->media()->sync($mediaIds);

Laravel - How to extract one field for items in a model to an array?

I have a table that has a one-to-many relationship with another table.
Call them tables parent and child
child has a field called field1
I am trying to get an array of all field1 values.
In the parent Model, I have this function that gets me all children of parent
public function children()
{
return $this->hasMany(Child::class);
}
Now, in the parent model, I also want to get all field1 values.
I can get all the children like so:
$children = $this->children->all();
But I just can't figure out how to then index into this to get all the field1 values.
Maybe it is better to just use $this->children in which case it is a Collection and then use some sort of Collection method to extract field1?
I tried
$this->children->only(['field1'])
but that returned nothing, even though field1 certain exists.
Ideas?
Thanks!
You can use pluck method of collecion to get an array of field1 values:
$parent->child->pluck('field1');
Or better, you can use pluck method of query builder (see section Retrieving A List Of Column Values), being even more efficient, with same result:
$parent->child()->pluck('field1');
map() is the function you are looking.
$children = $this->children->all()->map(function($children) {
return $children->field1;
});
A shorter version using Higher Order Message.
$children = $this->children->all()->map->field1;

Removing attributes from an activerecord got via .includes

I am having a really weird problem while attempting to do a very simple thing. I am doing an .includes on a model to get a row of data from the database. On the return object I need to remove certain attributes conditionally. And the final aim is to reinsert this row as a new record based on the changes I make on the attributes using my conditions.
def myUpdate
dbObj = Obj.includes(:name,
:addr1,
:addr2,
:state,
:description).find(params[:id])
#dbObjective.attributes().except('description')
#dbObjective.description = nil
#dbObjective.attributes().delete('description')
# After setting more attributes, persist this object
end
I tried all possibilities that I could think of, but the attribute is just not getting removed. What am I missing? I am on Ruby on Rails 4.2.
includes is used to include associated tables in your query for join queries and eager loading, not for table attributes. You do not need to do anything special to access an object's attributes.
attributes returns a Hash instance containing the record's attributes as key-value pairs, and operating on it will change only the Hash instance itself, not the record.
There are several ways to update attributes. One of the easiest ways is using the built in setter methods given to you by ActiveRecord. If you really want to change attributes using the Hash API you can store the attributes hash in a variable, manipulate the hash, and pass it as an argument to update, which accepts an attributes hash as it's argument.
Using setter methods
def myUpdate
dbObj = Obj.find(params[:id])
dbObj.description = 'new_description'
dbObj.name = 'new_name
dbObj.save
end
Using update
def myUpdate
dbObj = Obj.find(params[:id])
attributes = dbObj.attributes # This is how you would update the object by manipulating the attributes hash
attributes.delete(:description) # this will NOT end up changing the attribute in the DB
attributes[:name] = nil # this will successfully set name to NULL in the DB
dbObj.update(attributes) # pass the manipulated hash to the `update` method to persist the changes
end
deleteing fields from the hash will not have an effect on the persisted object. update only performs an insert on fields present in the hash that have changed.

Set values on Symfony2 validation with no form

I'm coding an API and I'm doing the create method. I'm doing the following without needing a form:
$params = array('title' => 'test', 'parent_id' => 781);
// bind data
$place = new Place();
$place->bind($params);
// validate params
$errors = $this->validator->validate($place);
I need to check that parent_id is a correct value (its object exist - i know how to do this) and after that, I need to set some values dependent on the parent. So at the end the Place object will have the fields: title, parent_id, level, country_id for example.
How would you do this? On the validation? How? If not, how to avoid calling two times the DB to get the parent object?
You should first validate & then set any additional values afterward. Anything that modifies the value does not belong in the validator.
If your using doctrine, it should load the parent object into memory when you first access it, so it won't need to actually query the database again when you access the parent object a second time.

Resources