I have a form with a "reset this collection" button. Looks kind of like this:
<button e-click="reset_patients">reset patients</button>
In my controller, I do this:
def reset_patients
puts "destroying"
store.patients.each{|p| p.destroy}
end
What I expect is that the clients displaying the list will show an empty list. What is actually happening is that some but not all of the items are deleted.
How is a "dump the entire collection in the trash can" operation handled on a persistent backed store (i.e.: model :store)? Also, is there a way to make these cascade through related collections?
We don't have .destroy_all yet. Its on my short list, but I'm reworking one thing in the data provider API to make it a bit smarter. For now you can do
store.patients.reverse.each(&:destroy)
(The .reverse is needed since your deleting array objects as you loop)
Related
I am displaying a tree and I need to add an element, but I want to keep the currently selected item.
If I do it like this:
oldSelectedItem := treePresenter selectedItem.
treePresenter
roots: newRootCollection;
selectItem: oldSelectedItem
it will of course work, but there is a problem: the activation event (whenActivatedDo:) will be triggered and I do not what this!
How can I proceed to avoid it?
Trees and Tree tables in spec implement the API updateRootsKeepingSelection: to prevent precisely this.
In practice, it makes the same as the code above, but it will not trigger any activation, and no activation transmission.
This code:
treePresenter updateRootsKeepingSelection: newRootCollection
Will have the same effect as the original code, but it will not trigger an activation when executed.
(Of course, to work properly is required that the new collection contains the previously selected elements).
In a to-do list where users have both system-created items and their own items, how would you store the items?
A to-do list can have a mix of items. The system-created items can be modified and deleted just like user-created items. There difference is the titles and description text for the system-created items are initially pulled from a configuration. Many users can have the same system-created items. E.g. if two users want to paint rooms in their houses, they'd both get "buy paint" items.
Option 1
Save the full system-created items (including the title & text) with the user-created items.
Pros: Flexibility for user modifications since the items belong to the user and are not dependent on a central item configuration.
Cons: Lots of redundancy because there will be many users all with the same items.
Option 2
Save references to a configuration for system-created items with the user-created items.
Pros: Flexibility for system modifications since if we want to say "buy X-brand paint" instead of "buy paint", the change is easily reflected for all users with this item.
Cons: System-created items have to persist forever in the configuration even if the item is no longer relevant for new to-do lists because otherwise the user's reference will be broken.
Other options?
Thank you!
My initial thought is - what is your requirement? Your user-flows and project road-map might contain information to inform your design.
From your question "system-created items can be modified and deleted just like user-created items":
This indicates that you are going to have to have a way to track modifications to your 'system-created' templates per user or convert them to 'user-created' messages when they are edited.
This is more complexity than you seem to need
It seems much simpler to create messages from system templates, then have them be regular messages.
A bit of extra storage is not going to break the bank
You have not mentioned any case where you would need to operate over only system-created to-do's. But in this case, you could include created-by metadata.
I think the key here is whether you need to be able to modify a "system todo", and that change to be reflected in all the "user todos"...
If that's a requirement (it sounds sensible to me), your only option is Option 2 - the real con of Option 1 is once you copied the "system todo" as a "user todo", you cannot tell anymore whether they're related...
I'd go for a model similar to this, with 2 entities/tables:
ToDoTemplate
Integer id
String name
String description
ToDoItem
Integer id
ToDoTemplate template
Boolean completed = false
?String name = null
?String description = null
When you create a ToDoItem, you create it based on a ToDoTemplate (it may be a blank template), and you set the name and description as null, reusing the template name/description... Only if the user modifies their own ToDoItem is when you store that value... i.e.
String getName() {
return this.name != null ? this.name : this.template.name;
}
This is the most flexible of the approaches, and the only valid in many situations... Note the con you mention:
Cons: System-created items have to persist forever in the configuration even if the item is no longer relevant for new to-do lists because otherwise the user's reference will be broken.
This is not a con really - as long as there's one ToDoItem that uses a given ToDoTemplate, the template is still relevant, and of course there's no reason to remove it...
The situation is like this:
We have a POWL, where I added a toobar-button.
The click on that button opens a FPM-POWL, which I created
with the help of this link
https://sapcodes.com/2016/03/25/powl-in-fpm/....
(INFO: This POWL takes it's data from a standard FBI View).
The new FPM-POWL is properly(??? I hope so, because it gets shown) maintained inside the LPD_CUST in order to start this popup inside the FPM-framework (flag that it should wait, is also set on caller and callee) .
Ok, let's proceed.--
The calling class (feeder class "A", implementing IF_POWL_FEEDER) calls the POPUP like this
DATA(lt_lpd_content) = lr_lpd_handle->mt_content.
READ TABLE lt_lpd_content
REFERENCE INTO DATA(lr_lpd_content)
WITH KEY application_alias = 'ZSRM_GP/BP_POPUP'.
lr_lpd_handle->launch_application( iv_application_id = lr_lpd_content->application_id ).
The user shall simply be able to pick one business partner....
After the user picks a record, and hits a special toolbar-button of the "popup", its feeder class "B"(also implementing IF_POWL_FEEDER) does, what it needs to do inside handle_action and until now... I try to figure out, HOW to pass the record back to the caller class "A"...
Because, unlike expected (because both LPD_CUST entries have the flag set "Synch/await"), the class "A" proceeds processing any code I place after
lr_lpd_handle->launch_application( iv_application_id = lr_lpd_content->application_id ).
And so I suppose, this is "works as designed" and is asynchroneous .
So, my current experiments assumed synchroneous, and I exported any picked business partner's number to a memory ID and closed the "popup".
But I never returned to the caller, where I wanted to start coding the rest of the requirement.
So, my second try is, that I created an event in feeder class "B" (called popup) and a handler for this inside feederclass "A" ( caller ).
Inside the ctor of class "A" I register via "SET HANDLER FOR ALL INSTANCES".... and the tests are just about to start.
But I really hate this approach,.... is there a best practice regarding this ?
I cannot imagine, that I am the only one with this kind of requirement, which, in simple terms, means:
"Listpopup"... and we all know, how simple this is in sapgui...but inside the FPM-POWL-LPD environment... I cannot get it...
EDIT: Maybe I should do something in here to FORCE a blocking popup call ?
Or can I somehow populate the exporting parameters of handle action of the callee to return to the callers handle_action ? Ala POWL_FORWARD_anything ?
I am currently developing an application in which i experience the exception "A cycle was detected in the set of changes" when calling DataContext.SubmitChanges(). I know why this exception is thrown but i have not been able to find a fix for my situation. Let me explain the situation. I have a database with a table as shown below which i access with LINQ to SQL so it gets mapped to classes in vb.net.
Device
-------
ID
DefaultGatewayID
The DefaultGatewayID is a Device an can even be the same object or another Device. The user uses a GUI with a DataGrid to alter and add new records. The updating records is no problem. The ID already exists and the DefaultGatewayObject is attached to the record (the ID is stored in database).
However when i try to add a new record and set the DefaultGatewayObject in the same transaction i get the 'Cycle detected in set of changes'-exception. I suspect this is caused by LINQ to SQL because it does not know which record to add first, although it is the same item in this case.
I do not have the option to break the insertion into two parts, one for the Device and then adding the DefaultGateway because my submit button is bound to a XAML Command which executes the SubmitChanges.
Ideally i would have some option to specify which object is to be created first, or something like that. I think it's an option to remove the connection to itself and just set the ID in this field, but i'd rather find a fix within LINQ to SQL.
I hope SO has an answer to this. I could only find this related post "Cycle detected while adding Circularly linked list"
You can break the insertion into two parts ans still have one transaction if you wrap your code in a TransactionScope.
Using trans As New TransactionScope()
'Code that generates a new ID in the database
dc.SubmitChanges()
'Code that uses the new ID value.
dc.SubmitChanges()
trans.Complete()
End Using
This is the only way to avoid the exception. If this is impossible because of architectural decisions ("my submit button is bound to a XAML Command") you need to change the architecture. I think a UI command should never be so close to the data access layer anyway. You better call a service method from XAML.
I want to create multiple entities from a single form with parameters that have the same name. I'm trying to create an array starting with 1 and ending in the max number of items in the array. Does entity framework do this by default.
Example:
PersonName(1): "Bob"
PersonName(2): "John"
PersonName(3): "Mindy"
If I loop through collections using entity framework is there a preferred method for name and id attributes.
Html:
<input name="personname(1)" id="personname(1)" value="Bob" /><br />
<input name="personname(2)" id="personname(1)" value="John" /><br />
<input name="personname(3)" id="personname(1)" value="Mindy" /><br />
Also I noticed that when I use #Html.EditorFor it has some overloaded methods to name the id and name attributes. So would it be recommend to build these using the template name set to empty string, and the
htmlFieldName="personname" + "(" + i + ")";
Or is there a preferred technique?
If you use the Html helpers, it does this for you automatically, especially if you use the EditorTemplates. For example:
#for(int i=0, i<collection.Count; i++)
{
Html.TextBoxFor(m => m.collection[i].Name);
<input type="submit"/>
}
This creates the input elements with the proper indexing. The better way is to simply use editor templates though:
#Html.EditorFor(m => m.collection)
You can loop through the collection using for loop. Appending [index] to personname.
For example:
for(int i = 0; i < personName.Length; i++)
{
<input name="personName[" + i + "]" id="personName_" + i value=personName[i] />
}
Note, that ID value cannot contain brackets, braces or similar, that is why you need to use something like underscore plus index value.
The correct answer is you have to add the parent table as the Model. In every reference to any child fields or child tables's fields you have to refer to this parent model first. All child models must drill down in the EditorFor's HiddenFor's, TextBoxFor's etc... by calling on the parent model first. Without the parent it won't know how to correctly relate to it when its time to perform the save changes or when editing it needs to check the proper references. Both the parent ids and child ids must be listed out in order to combine all tables in a single form and then perform a save changes on the fields. Otherwise it won't include those fields or it will not be able to save that table correctly and not auto generate... yes I said "auto generate" the ids. If you try and auto generate the ids yourself it will make maintenance a nightmare.
There... I filled in all the information a noob will need to surpass the point farmers.
So why is this important? Because if the #Model does not point to the top most object that all other object are related to then it doesn't know how the reference relates. Example would be a Document table. But the Document table might have a foreign key to a Title table. That would be one to one. The Document table would still need to be listed first like so Document.Title.TitleName. In a one to many like in an Author... b/c there might be more than one Author.. you would still list Document first. As in Document.Authors ... author would be a collection so you would loop through each author. But at the very top even in Partials you would still only reference #modelDocument and not the author, that would be after the #Model portion in the content area. If you try and reference just the #model author portion. Now it doesn't understand how it relates to the document and you either have to add the document identifier inside the author table's foreign key for the documentid at some point later downstream after adding the author. This is unfortunate as its not necessary if you just started with the Document to begin with.
Of course this can get a little more complicated b/c you can have more than one document per author so a linking table to a documentauthors table would be preferable here... but still Document table would still be listed at the top of a partial view and even the main view in order to completely place the correct identifiers and names in an html page so that when the form is submitted it properly knows how everything is realted. Also the identifiers should be placed in the html helpers for hidden input fields if they are not to be displayed outwardly to the users.
Now to make it an incremented number of times and to start with a certain grouping... it would require a query string or a posting attributes to send the start and stop range for that group or list of authors, or list of books, or documents or whatever. Since the one to many and many to many relationships should be output in for loops, it can select the correct relationships to retrieve and select also the ones to be displayed using linq for the entity framework which is supplied in a private member variable that allow you to perform database crud ops.
For the point farmers... nothing.