How to add Collection Level Validation - breeze

How would i implement collection level validation in Breeze.
Say i have a collection of 3 rows. I want to make sure the sum of %Used column is 100.
The number of Rows can vary(dynamic) it can be any where between 1-10 rows.
each parent row can have different collection of child rows
a) Parent Row1
ID %used
1 20
2 40
3 40
========
100
b) Parent Row 2
ID %used
1) 50
2) 50
========
100
and so on

So just to clarify, I am assuming that your issue is that you have an entityType that has a collection navigation property, the contents of which you want to validate. An example might be that you want to insure that the total freight costs of all of the order details within an order are less than $100.
This can be done by adding an 'entity level' validation to the entityType. i.e. something like
myEntityType = myEntityManager.getEntityType("Foo");
myEntityType.validators.add( myCustomValidator);
Please read the breeze validation documentation here for more information.
The validator itself should basically iterate over the results returned from the desired navigation property and perform its validation over some aggregate that you calculate during the iteration process.
Entity level validations, such as this, will automatically execute during the save process, but if you want this validation to be performed whenever the 'contents' of the navigation property are modified you will also want to look at the 'relationArray.arrayChanged' event. Every collection navigation property in breeze is a 'relationArray', so you can subscribe to this event on each relation array that you are interested in and call the parent entity validation whenever you see a change.
We are hoping to add additional validation examples to the breeze documentation at some point. Please add this item and vote for it on the breeze User Voice if you feel that this would be helpful.
Hope this helps.

Related

How to build relational tables in a two-sided marketplace

I'm really struggling with this problem, would love some additional thoughts. Here's the basic context:
Users can both list items to be lent out, and make requests for items to borrow
Requests are posted by users who want to borrow something. Each request may contain several items
Items are predefined (i.e., POST form is a checkbox) and listed by users who want to lend them out, and are in turn borrowed by other users who have submitted a request
Workflow:
John is a user and submits a request for a tent from 6/5 to 6/8
The controller looks for all users (besides John) who own tents that are available from 6/5 to 6/8
This list of users are contacted to see who wants to provide a tent for John
Whoever responds affirmative to John first has their item in the table automatically updated to be no longer available from 6/5 to 6/8
John and the other user are connected to make the exchange happen
So far my thinking:
Users table has_many :items and has_many :requests
Requests table belongs_to :users
Items table belongs_to :users
Additional complexities that my brain can't seem to process:
One request can contain multiple items, and I've been told against accepting items as a serialized array in one cell, so then I'm not sure how to relate request and item. In the tables above, should items also belong_to requests? And if yes, this seems to imply that a user has to make a request for a specific item whereas I want the user to be able to search for tent, and see a list of all the users who have tents that are available
Requests contain start_date and end_date attributes, that somehow need to be compared to when the item is available. Right now I'm thinking in the items table, there needs to be a column that stores the dates when the item will be in use (i.e., not available). But then this data will be an array again. For example, a tent might be requested (and the user responds OK) from 6/5 to 6/8 and then again from 6/10 to 6/15, and then again from 7/8 to 7/9. So do I need a fourth table??
Items will be a predefined list, e.g., tent, sleeping bag, sleeping pad. In this way, I'm wondering do I actually need a has_and_belongs_to_many relationship with users, since a tent could belong to many users, and a user could have many tents.
Sorry if this sounds like a ramble... I've been sitting here for 4 hours with many sheets of paper and scribbles and this is not getting any clearer...
You need to understand the basic way of recording information relationally ie in tables.
Finding sufficient tables
Just have a base table for every statement you need to describe a business situation:
User(user_id,name,...)
// User [user_id] is named [name]
Contacted(contact_id,item,offer_id)
// user [contact_id] was contacted re item [item] offered by user [offer_id]
...etc...
The parameters of the statement are the columns of the table.
If you want to talk about the parts of something that you think of as having multiple parts (heterogenous or homogeneous) that just means that some statements will involve a thing and its parts:
table request(request_id,start_date,end_date,...)
// [request_id] goes from [start_date] to [end_date] and ...
table requested(request_id,item_id,person_id,...)
// person [person_id] requested item [item_id] in request [request_id]
What's in a table
A base table's value is the rows that make its statement true. (Every query subexpression also has a statement, and its value is the rows that make its statement true.)
Don't confuse table statements with business rules. Business rules state truths. But a table statement is a statement that some tuple makes true (and goes in the table) or false (is left out of the table). All the true and false statements from the tables tell you everything you need to know about the business. The business rules will never contradict them. (Since they're always true.)
Rearranging to better tables
A key is a set of columns that all other columns are such functions of but none of whose subsets have that property. A table can have more than one key.
To make a database easier to update and query you should break up certain statements that are other statements joined by AND. Break up until each statement consists of a statement only about key columns ANDed with statements of this form:
[my_column]=my_function([key_k_column_1],[key_k_column_2],...)
where key_k_column_1,... are columns of the same key key_n.
(Such a table is "in fifth normal form" and the topic is "normalization".)

NSFetchRequestController use sectioning parameter as part of title for section

I have a Core Data application with two entities. One is the Order Entity and the other is the Sales Order Numberentity. The Order entity contains an attribute that basically represents which sales order number it is a part of. I am using an NSFetchedResultsController to try and group this list of orders by sales order number. This is done using the sectionNameKeyPath parameter of the init method of NSFetchedResultsController. However, I want to use attributes of the Sales Order Number entity in the header of the section and this is proving annoying. I could get the first Order in the section and then backtrack from there using the relationship to get the Sales Order Number that it belongs to and then pull attributes from there, but is there a better way to accomplish what I am trying to do?
Sorry if this is unclear.

Hide Duplicate Rows in Core Data Driven UITableView

I have a Core Data entity that has two name attributes and several other numeric attributes. The sort is on the numeric attributes first and last on the name attributes. Data is coming from multiple sources and so it is possible to get duplicate rows where the names are switched in order. i.e. row 1 has names Bill and Ed, where row 2 has names Ed and Bill. The rows are identical, except for the fact that the order of the names is switched.
I was hoping that there might be a way to 'hide' the duplicate rows in the table view, but since the row count is coming from the fetchedresults controller, I can't see how that would work.
Any suggestions on how to proceed?
Jim
I think the best approach is to create an array containing all the data you actually want to display. You can assign your first source to the array and for the other ones you first verify that the item doesn't exist before adding it. If you know how the duplicates can be presented then you can write the necessary conditions that need to be passed before adding it to the array.

DB grid : How to use a column of the current row of one as an index into another?

I am not sure if the question title is clear enough, please feel free to edit it.
Basically, I have two DB grids which reflect two database tables, each grid showing one.
When the user selects a row in the first table (let's call it oders), I want to update the second with details of any rows matching a column of the selected row of the first table.
Say, for instance that table orders has a column customer_id and I want to populate the second table (let's call it order_details) with details of all orders from that customer, one order per row.
I can connect up 2 # datasource, query and connection to the two TDbGrids, but I am stuck as to how to code order_details SQL.
The SQL for orders is just SELECT * from orders, but the other?
I want something like SELECT * from order_details WHERE cutomer_id=<orderQuery>.currentRow.FieldByName("customer_id").AsInteger - but I don't know how to do that ...
Can someone help me with some Delphi code?
Also, once I set up that relationship, will selecting a new row in the orders DB grid automatically update the order_details DB grid? Or do I need to add code for that.
P.s I know that there is no books tag anymore (more's the pity), but can someone recommend a good book which explains the fundamentals of programming DB aware controls? I obviously need one. Thanks
Use a parameterized query for the detail (child) database:
SELECT * FROM Order_Details od WHERE od.CustomerID = :CustomerID
Then set the child query's MasterSource to the parent (Order) datasource, and the MasterFields to CustomerID. (If there are multiple columns that link the two, separate them by ;, as in CustomerID;OrderNumber.)
Every time you scroll the parent (change the selected record in the parent DBGrid), the child query will be executed with the ID of the parent row passed as a parameter automatically.

Editable detail records in Delphi DBGrid

I have a database (held in an Access .MDB file) that records staff members, and any absence they have e.g. holiday, sickness, training course, the start and end dates, and hours of productive time lost.
I then have a dbgrid bound to an "master" ADO query that finds all staff meeting the selected criteria of date range, department, search string for name, summing up the hours of productive time lost.
I have another dbgrid bound to a "detail" ADO table containing the absence records.
The desired effect is that the detail dbgrid should only contain those records from the Absence table that match the row selected in the master record (both "master" Staff and "detail" Absence tables contain a common EmployeeID field).
Though I can achieve this using ADO Queries created on the fly, changing the query each time the user moves to a different master staff record, I was hoping to use the detail DBGrid as my main method of deleting, updating, and adding additional absence records, complete with in grid lookups; so user can select record types without having to remember the code for that type.
I would also like the changes in this detail grid to be reflected in the summaries in the master dbgrid.
I have achieved this using a detail ADOTable linked as MasterDetail to the Staff Query, but need to have filtered set to True, and control the onfilterevent in code; but as the database increases in size this is getting slower and slower.
Is there anything I can do to improve this performance, or will I be forced to have the detail dbgrid as purely read-only, and all Absence records entered through another form or panel?
More information on Making the Table a Detail of Another Dataset
ADOTable2.MasterSource := DataSource1;
ADOTable2.MasterFields := 'EmployeeID';
I would also like the changes in this detail grid to be reflected in the summaries in the master dbgrid. After editing the detail table and posting any change you may use the AfterPost event to recalculate the summaries.

Resources