When creating new database records, TYPO3 assigns them a temporary UID, which looks like this: NEW56fe740dd5a455.64167468. The record gets its real UID when it is inserted into the database.
In the above hook, the record is already inserted into the database, so it has a numerical uid assigned. How do I get that uid from a given temporary UID?
Ok, found it. The fourth parameter of the hook-method is the datahandler object, which has a property substNEWwithIDs, an associative array mapping temporary UIDs to the real UIDs.
One can use it like this:
public function processDatamap_afterDatabaseOperations($action, $table, $uid, $datahandler)
{
if (GeneralUtility::isFirstPartOfStr($uid, 'NEW')) {
$uid = $datahandler->substNEWwithIDs[$uid];
}
// Do something with the UID
}
Related
I use Hasura and I have a social-network like situation.
In which I have a "User" object and a "Feed" object.
Every user has a feed.
I have a relationship from user.id to feed.id.
The relevant mutation is UpsertUserDetails as follows:
mutation UserDetailsUpsert(
$email: String!
$picture: String
) {
insert_users_one(
object: {
email: $email
feed: { data: {} }
picture: $picture
}
on_conflict: { constraint: users_tid_email_key, update_columns: [picture] }
) {
id
}
}
So when I create a new user it also creates a feed for it.
But when I only update user details I don't want it to create a new feed.
I would like to stop the upsert from going through to relationships instead of the above default behavior.
and according to this manual I don't see if its even possible: https://hasura.io/docs/latest/graphql/core/databases/postgres/mutations/upsert.html#upsert-in-nested-mutations
To allow upserting in nested cases, set update_columns: []. By doing this, in case of a conflict, the conflicted column/s will be updated with the new value (which is the same values as they had before and hence will effectively leave them unchanged) and will allow the upsert to go through.
Thanks!
I'd recommend that you design your schema such that bad data cannot be entered in the first place. You can put partial unique indices on the feed table in order to prevent duplicate feeds from ever being created. Since you have both users and groups you can implement it with 2 partial indices.
CREATE UNIQUE INDEX unique_feed_per_user ON feed (user_id)
WHERE user_id IS NOT NULL;
CREATE UNIQUE INDEX unique_feed_per_group ON feed (group_id)
WHERE group_id IS NOT NULL;
I am creating a collection of judges and courthouses. Every judge will be assigned to one courthouse. I have set up my relation to be that courthouse has many judges
I am attempting to do this programmatically when the app loads. I have a function that is able to populate all the fields in judge except the relation to courthouse. My function uses the Strapi API like this
const judge = await strapi.query('judge').create({
name: data[i].name,
},
{
courthouse: data[i].courthouse_name // here is where I think the relation is created
}
)
I am passing in a string that has the name of courthouse, because I don't know the ID of the courthouse in the Courthouse collection.
My question is it possible to create a relation to another collection by anything other than an ID? How can I create a relation to a courthouse by its name?
I couldn't find a way around building a relationship between two models without the ID, so I created a custom solution using the Strapi lifecycle hooks
Essentially what I did I utilized the beforeCreate lifecycle hook to query and find the courthouse that matches the name like this:
// judges.js
async beforeCreate(result, data) {
const courthouse = await strapi.query('courthouse').find(
{courthouse_name:data.courthouse}
); // returns the courthouse that matches the name
result['courthouse'] = courthouse[0].id; // populates the relational field with the
// ID of the courthouse
}
The response object contained the courthouse's ID and I manipulated the data that is being sent to the create command like this:
const judge = await strapi.query('judge').create({
name: data[i].name,
courthouse: data[i].courthouse_name
})
The result is an object that looks like this:
{name: 'Garfield Lucas, courthouse: 7463987}
I have a postgres table in which I have some "defaulted" fields like date_created which automatically receives a current_timestamp as default.
or the ID field which gets it's value from a sequence defined in the database.
What would be (if possible) the syntax to tell the ORM module to not include these two fields when generating an INSERT statement ?
You can use a function as 2nd parameter to remove the fields:
$this->copyfrom('POST',function($val) {
unset($val['ID']);
unset($val['date_created']);
return $val
});
or to only copy allowed fields from the POST array:
$this->copyfrom('POST',function($val) {
return array_intersect_key($val, array_flip(array('name','age')));
});
Assuming you are using an HTML form to add new records into the tables, follow the steps below;
In the form, omit these 'defaulted' fields, i.e. add only the fields that you want to submit
Create a model with a function similar to below
public function add() {
$this->copyFrom ( 'POST' );
$this->save ();
}
Create a route that links the form to this function
So, i'm creating collection as suggested in angular2-meteor boilerplate:
export const BookCollection = new MongoObservable.Collection<Book>('books');
So, if i write something like this:
BookColletion.insert(..., callback_f);
I'm getting an error, that second parameter does not exists. So, how i supposed to get last inserted document's id?
I'm not sure what MongoObservable is, nor what that <Book> syntax means, but I suspect that what you want is something like this:
export const BookCollection = new Mongo.Collection('books');
BookCollection.find().observe({
added(document) {
// document is the newly added document
}
});
You can get the inserted id like this:
var insertedId = BookColletion.collection.insert();
as mentioned here
Assuming I have a Plugin MyExtPlugin and has a record MyExtPlugin_Record_A and this record has a field status.
The DB field of MyExtPlugin_Record_A are uid,name,status .
For status in TCA form:
'status'=>array(
'type' => 'user'
'userFunc' => 'EXT:userClass.specialFunction'
)
My specialFunction should do something like this:
current_uid_of_record= #get current uid of the record;
current_status= #get status for current_uid_of_record
if (current_status==0)
return 'Pending';
return 'Approved';
Question: How do I get that current Uid of that record which is being added or edited?
Try this:
public function specialFunction($PA, $fobj) {
$current_uid_of_record = $PA['row']['uid'];
// ...
}
Be aware though that the UID is never 0. It's either a number >0 or a temporary UID which is a string starting with letters.