Related tables, filters and conditions - erp

I have a new table where one of his fields is related to Table Items. I want to place a filter in one of the function fields Item Category pointing register the Item table, but do not know how this dual role. I hope it was not too confusing ..

Related

Master/Child with alternative linking fields in the child table

There is probably a simple solution to this but I'm stumped.
I have a master table with one ID field. There is a child table with that ID in two possible fields. Think of a doubles team with Player A and Player B. The Master table will have two records, one for each player. The Child will have one record with the Player A ID in one field and the Player B ID in a second field.
When I use the Master/Child and I'm sitting on Player A I will only see the child records if Player A is in the first ID field. If I move to Player B then I see nothing in the child table if Player B ID is in the second field.
Any help?
Thanks,
Don
Gday,
If I read you aright, you want to return each child row that has the parent ID in either A or B.
To do this in a query, you could write:
select A, field1, field2...
from
childtable
where
A = :keyvalue
union all
select B, field1, field2...
from
childtable
where
B = :keyvalue
Hope it helps!
The Child will have one record with the Player A ID in one field and the Player B ID in a second field.
In that case, you should consider using an fkInternalCalc field on the Detail table (if your TDataSet type supports fkInternalCalc fields, and deriving its value in the Detail's OnCalcFields event however suits your data model) and use that as the Detail field in an Index on the Detail table for selecting records which match the master. But generally speaking, needing to do that (i.e, link the Detail records on values from different fields) is a sign of imperfect data-modelling** - you might do better to have an intermediate "linking" table between the two tables you currently have,e.g. linking the Detail records to the Master on the basis of PlayerID, regardless of whether the player is "PlayerA" or "PlayerB".
** - the reason being that, as you have obviously gathered, the Master could be linked to the Detail on the basis of two different fields in the Detail table, and that does not fit with how M-D relationships traditionally work in Delphi (i.e. a single field or combination of fields with no alternatives) and in fact an extra, "linking" table is the better way to model the situation where the link needs to be defined on the basis of the values in Detail fields IDFieldA and IDFieldB.
Btw, what TDataSet descendant types are you using?
The simpler and much faster running answer to the UNION ALL join is
SELECT Mast.* ,DetA.* ,DetB.* FROM
MAST
JOIN Det AS DetA ON Mast.AID=DetA.Det_ID
JOIN Det AS DetB ON Mast.BID=DetB.Det_ID
If you want to be able to have any number of players in the game, then each Det record (player) needs to point to the master using the Mast_ID. You can do a similar join that way, but you will get one record per player if you do. The way I did it above gives you one record for each master/detail A/Detail B combination.

Sorting a nested collectionDatasource in Cuba Framework

I have a bookDatasource. One book has many authors. The collection is displayed in a grid on the book-edit-view. Now I want to sort by authors name. In the collectionDatasource properties I set sortable to true.
How can I do it?
If I understand correctly, you're binding Table and Book Authors using nested datasource, like that:
<datasource id="bookDs"
class="com.company.test.entity.Book"
view="book-edit-view">
<collectionDatasource id="authorsDs" property="authors"/>
</datasource>
If so, first, ensure that Book entity has collection of Authors attribute of ordered type (List or LinkedHashSet). If its not you can change collection type in Studio or manually in Book entity.
Then table column becomes sortable - when user clicks on column header table will sort rows accordingly. Also CUBA Platform will handle saving sorting setting as user settings - so next time user opens the screen table will be sorted.
In order to enable sorting of Book Authors by default you could do it on ORM level. In Studio open entity Book, click on authors attribute and set value name in Order by field in attribute properties panel. This will ensure that any instance of Book entity has authors sorted by name.

Backendless iOS: intermediate table between two tables

I am new in Backendless and I have read all the manuals about relations, but still not sure how to create san intermediate table between two tables.
For instance, I have table called users and tables called Events. A user can subscribe to events. So I want new table UserEvents, which has user_id and event_id. Also, how would I retrieve all events added by user? In other words, how to do joins in Backendless?(I suppose there is no joins and everything much simpler though).
Thank you very much!
There are two separate questions at hand here:
How to create relationships between objects?
How to load objects created by a user?
Let's start with the first one:
How to create relationships between objects?
When you work with Backendless it is important to think in terms of objects and not tables. For example if there is an entity called Order and it contains a collection of OrderItem objects, then THAT is your data structure. You do not need to pre-create tables in console – Backendless will do it for you the very first time you save an Order object which has a collection of OrderItems. However, if you would like to do it by hand in our Console, here are the steps:
Login to console, select an app, click on Data
Create table Order (it is better to name tables in the singular form - so Order, not Orders).
When you create a new table (click the "+" button in the lower-left corner), console will prompt you to switch to Schema Editor so you can add some data columns. A column would correspond to a property in the class which represents a record from the table.
Now that the Order table is in place, repeat the process for the OrderItem table.
Once both tables exist, we need to "link" the tables together. That link would establish a relationship which can be either one-to-one or one-to-many. To do this, select the Order table and click the Table Schema and Permissions red button in the upper right corner.
Click the Add Relationship button.
In the popup that appears, you will need to create a property which will contain a collection of order item objects. Name that property "orderItems" (it is okay to make it plural here). On the right side of the popup select the OrderItem table. In the Multiplicity drop-down select Many.
Click Save. At this point the relationship is established.
To see it working you can either use the code generation module which will give you all the source code for working with the tables. Click the Code Generation icon. In the Android section, select either Eclipse or IDEA in the IDE block, then click the Java classes for defined data tables option. Click Download Project. Backendless will generate a ZIP file with the source code for the client-side classes that will let you perform a full CRUD (Create, Retrieve, Update, Delete) range of operations on your tables.
The documentation describes how to work with related data. For instance, see the approaches and API for retrieving related objects.
Things are simpler when it comes to the question of how to load objects created by a user. So we come to the second question:
How to load objects created by a user?
The approach described above works equally well for linking the built-in Users table with any other table. However, specifically with the Users table, that link/relationship is not necessary. The reason for this is Backendless automatically tags any created object with the ID of the "owner", that is the user who created the object. That "tag" can be seen with the special ownerId property in the Users table. To enable retrieval of the objects which belong to the user, we need to modify the security permissions for the table which contains the objects created by users:
Login to console, select your app and click the Data icon.
Select the table with the objects created by users.
Click the Table Security and Permissions red button in the upper right corner of the screen.
Click the Role Permissions menu item.
Locate the cell at the intersection of the Find column and the AuthenticatedUser row. Click the cell until you see a red cross.
Repeat the previous step for the intersection of the Find column and the NotAuthenticatedUser row.
At this point you restricted all access to your table for both authenticated and not-authenticated (guest) users. The next step will allow the owners to retrieve the objects which they created.
Click the Owner Policy menu item.
Click the cell in the Find column until there is a green check mark.
At this point when you call any of the Find methods on that table, Backendless will return only the objects which belong to the currently logged in user.

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.

How to Manage Dynamic Relationships?

I need help creating an appropriate database structure that will allow me to dynamically create "fields" and "values". I plan on using the following 5 tables.
TraitCategories
Groups
TraitGroupings
People
TraitValues
TraitCategories table holds only categories (i.e. "fields") of traits -- i.e. hair color, height, etc. -- and the categories can be added/removed as desired.
Groups table holds ad hoc/dynamic group labels -- i.e. Asian, South American, etc.
TraitGroupings is the join table for TraitCategories and Groups
The People table will be linked to the Groups table via a foreign key and thus will be assigned various categories (fields) of traits by leveraging the relationship between the Groups and TraitCategories tables.
But the question is, how do I assign per person values to the trait categories/fields?
I was thinking of having each row in the TraitValues table contain person_id and trait_category_id so that there will be a relationship between the TraitValues table and both the People and TraitCategories tables. Does this approach make sense? Will this approach allow me to get trait categories and values via the People table?
You are describing a form of EAV.
I'm not sure how practical this is going to be for representing in Ruby, but in you case, the database model would look similar to this:
(Most non-key fields omitted, for brevity.)
Note how we abundantly use the identifying relationships. This is what lets us propagate GroupId down both sides of the "diamond-shaped" dependency, and merge it into a single field at the bottom, in TraitValue.
This is what ensures a person cannot have a trait, unless it is also listed for that person's group. For example, a person can have a "hair color" only if the person's group has the "hair color" as well.
BTW...
The People table will be linked to the TraitGroupings via a foreign key -- and thus will be assigned various categories (fields) of traits.
If People has a FK that directly references TraitGroupings, then a person can have at most one trait grouping and therefore at most one trait category. From the wording of your question, that desn't appear to be what you want.

Resources