Modify / Update element in ArrayList in working memory in rule Drools - drools

We are working on a rule that is structured as follows:
We have a list that contains validated and non-validated elements. The difference between validated and non-validated is done by giving a different status to the elements.
We obtain the non-validated elements from the list.
Each non-validated element is compared to the validated elements in the same list.
After comparison a non-validated element would become a validated element that needs to be considered when validating the non-validated elements.
The problem arises when we want to update the original ArrayList of elements. We need to be able to update the non-validated element that has just become validated in its original ArrayList in the working memory so the loop can take the "refreshed" ArrayList into account.
Three questions:
First of all, what is the exact difference between using modify and update in Drools. According to Drools documentation:
"On the right hand side of a rule the modifystatement is recommended,
as it makes the changes and notifies the engine in a single
statement."
So the difference between one and other would be just simple semantics like:
modify( $sprinkler ) { setOn( true ) };
and
$sprinkler.setOn(true);
update($sprinkler);
Is this assumption correct?
Secondly, is it possible to update or modify a specific element within the ArrayList in the working memory in Drools without using a plain Java iterator (a "for"). In our case each element is identified with a unique ID we obtain from the list so we will have a valid reference for updating its status (validated or non-validated).
Finally, we are aware that updating the working memory would cause the rule to fire again. Let's say we have an ArrayList with two non-validated items. If we were to obtain all non-validated items to validate them, I would create a rule "first" that fires twice, for each non-validated item once:
rule "first"
when
$listOfElements : java.util.ArrayList ( )
$itemsToValidate : Element ( status == "not validated" ) from $listOfElements
then
//do something or not
end
If in a second rule I would validate certain items and wish to change the status of the non-validated element to validated in the working memory like this:
rule "second" extends "first"
when
//we validate attributes of the non-validated element against attributes of the validated elements
then
//my second question is if something like this is actually possible (solution without Java iterator)
$itemsToValidate.setStatus("validated")
modify ($listOfElements) { $itemsToValidate };
end
How would this affect the whole process? The actualisation of the working memory will provoke the first rule to be reevaluated. This rule would already be launched twice because we had encountered two non-validated elements. Will the remaining element be evaluated only once or more than once?

The answer to your first question is that there is no difference between the two snippets. (Statements inserted between the two of the second one would influence my answer.)
The scenario for the second question doesn't use an update in the same form. Inserting a List as a fact but operating on list elements is usually considered as bad. Insert the list elements. The container may or may not be useful as a container holding the list elements to one transaction or whatever.

Related

Firestore Security Rule List Check Duplicate

Let's say that request.resource.data[field] is a list. I am trying to check if any of the items in the list is a duplicate of the other items. In other words, I am checking if any of the items are repeated more than once inside the list. I read the documentation and reference related to list, and did not find a way to implement this. Is this possible to do?
You can check to see if there are any duplicates in a List type field by:
Converting the List into a Set using toSet() (which cannot contain duplicates
Comparing the size of the List to the size of the Set
If the size of the set is less then the size of the list, then you know that there was at least one duplicate that got removed. So, something like this will return true if there was a duplicate in the list:
listField.toSet().size() < listField.size()

Filemaker value validation against value list

Need to validate values within a field against Value List, retaining the value if on list but substituting a specific Value if not?
I am afraid you are mixing two separate things:
Validation checks if some conditions have been satisfied; if not, it throws an error. It will not correct the entry.
If you want user entry to be corrected, you need to either:
define the field to auto-enter a calculated value; or
attach a script trigger to it, and have the script modify the value entered by the user.
In this case, you could auto-enter a calculated value (replacing existing value) =
If ( IsEmpty ( FilterValues ( Self ; ValueListItems ( Get (FileName) ; "YourValueList" ) ) ) ; "Specific Value" ; Self )
--- Added in response to your clarification ---
Technically, you could run a script to find the records you want to verify and do Replace Field Contents (using the same calculation) on that field. You could run the script after changing the value list, as part of the weekly routine.
However, there are two major problems with this approach:
some records could be locked by another user;
you have no history of what happened, and no way to go back in case of making a mistake.
I also don't think it's good practice to have users modify a value list routinely. If you need to have a weekly list of values, you should store them in records, not in a value list. That way at least the part of the value list would have a history.
Another option you may consider is using an unstored calculation field with a similar formula. This would change dynamically with the value list, and leave the original field unmodified. This would be a good arrangement if, for example, you need to export the corrected values every week.

How to sort subset of DataView?

How to sort subset of DataView? I use Sort property of DataView. Is it possible to sort all records except last added (let's name it "new record") - waiting until user complete entering data in fields of this new record and then initiating sort of the whole DataView.
I know it's been a while and you've moved on. But for future generations, if you use DataView.NewRow() and before you do Row.EndEdit() you can get the other rows by setting your DataView.RowStateFilter to DataViewRowState.OriginalRows.
You retain the new row, can work with those that match the filter. I would imagine that you then set the filter back to current before doing Row.EndEdit() but I've never done this particular move.
You can also use DataView.Table.NewRow(). This won't be added to your dataview until you perform DataView.Table.Rows.Add(Row). That is how I always do it - I think it is easier.

Run VBA code after form load

I have this continuous form "Results" built on a "Search" query in Microsoft Access and I want to show a hidden text field "Number" (with its Visible property initially set to False) depending on the value of one query result written in a "Type" combo box. My code is currently as follows:
Private Sub Form_Load()
If Me.Type="Reclamation" Then
Me.Number.Visible=True
Else: Me.Number.Visible=False
End If
End Sub
This does not seem to work, however the code does fine when triggered by a change event. Adding, changing and deleting records are also disabled in "Results".
Should I run code from a macro, on the query or try another event (I've tried many events though with no success)?
Thanks for the help, and sorry for the noob question!
Continuous Forms behave differently than what you think. It cannot work with UnBound Controls. If the control Number is bound it will take effect on only the Record that has foucs. Using Form Current combined with Load should/might work, but again it will not be the best solution. Because it will be applied to all other records in the SubForm.
Example of what I mean is, if the form has three records. First Record has Type (a terrible field/control name) "Reclamation" then the "current" record's Number (again a very bad field/control name) will be hidden along with all the other record's Number, even if they have other Type's in their record.
I would suggest you to go with Single Form.

Symfony 2 collection unique elements constraint, mapping errors to children

I have a formtype with single field: collection, containing unspecified number of anonymous selects. Is there a way to check if there are duplicate choices using builtin constraints? In case I have to write constraint myself, there is another problem. If I add the constraint on parent, how can I add error to child on specific index? If I add the constraint on children using All - how can I access values of other children?
Selects are allowed to return null value. The form is not bound to entity.
Thank you.
Ok, after digging through 10 pages of Google and SO results, I didn't find anything. So, I dug further, and as often happens, I've found solution in unit tests - symfony github link to this specific thing which solved my problem.
Now when I want to add error to specific field in collection, I can do:
$this->context->addViolationAt('['.$i.']', 'Error in field %d', $i);
This is case for unnamed collection children with default numeric indexes, I didn't test it with named ones. Also - remember about collection having error_bubbling enabled by default.