C1 Orckestra - Can a Global Datatype have a 1 to many relationship? - c1-cms

Is it possible to create a global datatype that has a 1 to many relationship?
Example
Create a global datatype for Dogs (some object on the website)
ID is a unique 8 character random string
Each Dog has several properties. (color, size, and so on)
Each Dog has many pictures. (as many as you would like, 1toMany)
I can see how you can assign a "C1 Media Folder" to a field, but what we are trying to achieve, is when you are editing the Dog's data (or adding a new one), you can add as many pictures as you want at this moment. It would be nice if the media folder was created at the moment the new Dog's data object is created, and it uses the unique ID from them Dog object to name the Media Folder. This gets us close to what we want, but it still means you have to jump over to the Media Library to upload the images you want tied to the Dog object.
If this is not possible with the current C1 console, does the C1 API allow us to code our own methods for adding images to the media library?
Thank you.

Your question seems to me to be not 100% specific, many things going on here which all should have its own question.
To answer what i see as the primary question based on the title, the answer is that you can do it in two ways.
Your pictures-field of the Dog object would contain a comma-separated list of media-item ids. This is the "C1" way of doing a 1-many relation and is what all the build-in multi-selector widgets in the C1 console supports.
Create a separate relationship holder object, call it DogPictureRelation which has a reference to a Dog objects and a Media object. And maybe a LocalOrdering field if the order of the pictures matters. This is the more correct way in a database world -we call it a relationship table, but unfortunately the built-in widgets don't support this and you would have to create your own Pictures-selector widget do work with this kind of datastructure.

Related

Should I create a reference field or a third content type to represent a many-to-many relationship in Drupal 8?

I have a student table and a course table that have a many-to-many relationship (a student can take many courses, and a course can be taken by many students).
If I am implementing the above data model as a database, I would create a third table to represent the many-to-many relationship.
But I want to implement the above data model in Drupal 8. I think that in Drupal 8 there are two ways to implement the above data model:
I can create a reference field in one of the two content types
(student or course) that points to the other content type.
I can create a third content type that have two reference fields
that points to the student and course content types.
Am I correct that these two ways are valid? and if I am correct, which one should I choose?
I think you're right, I would have suggested both ways.
As long as their connection doesn't have any additional parameters (e.g. date of subscription etc.), I would choose the entity reference within the students' content type.
Both of these are valid, and there's an additional option of having a corresponding reference field on each of your content types.
The best option comes down to maintain ability for your editors.
As per #c1u31355, if there is additional "connection" metadata, then a third content type is the way to go (or maybe a paragraph).
If it's a straight connection A <> B, and you only want the reference in one place, then ask yourself where is most convenient to add that data? Is it easier to create a course and then link to 30 students, or are you wanting to add courses to students as you create them? Quicker at creation, but harder to maintain.
Either way, using IEF as I suggested in one of your other questions will help.
As a final thought, having a 3rd content type could cause all sorts of issues unless you control the fields well, something like limiting it to only having one student with a bunch of courses, or vise versa, and in that case maintenance will be easier by just putting a reference field on the content type where you have restricted the field to one value.

Designing a database with similar, but different Models

I have a system whereby you can create documents. You select the document type to create and a form is displayed. Data is then added to the form, and the document can be generated. In Laravel things are done via Models. I am creating a new Model for each document but I don't think this is the best way. An example of my database :
So at the heart of it are projects. I create a new project; I can now create documents for this project. When I select project brief from a select box, a form is displayed whereby I can input :
Project roles
Project Data
Deliverables
Budget
It's three text fields and a standard input field. If I select reporting doc from the select menu, I have to input the data for this document (which is a couple of normal inputs, a couple of text fields, and a date). Although they are both documents, they expect different data (which is why I have created a Model for each document).
The problems: As seen in the diagram, I want to allow supporting documents to be uploaded alongside a document which is generated. I have a doc_upload table for this. So a document can have one or more doc_uploads.
Going back to the MVC structure, in my DocUpload model I can't say that DocUpload belongs to both ProjectBriefDoc and ProjectReportingDoc because it can only belong to one Model. So not only am I going to create a new model for every single document, I will have to create a new Upload model for each document as well. As more documents are added, I can see this becoming a nightmare to manage.
I am after a more generic Model which can handle different types of documents. My question relates to the different types of data I need to capture for each document, and how I can fit this into my design.
I have a design that can work, but I think it is a bad idea. I am looking for advice to improve this design, taking into account that each document requires different input, and each document will need to allow for file uploads.
You don't need to have a table/Model for each document type you'll create.
A more flexible approach would be to have a project_documents table, where you'll have a project_id and some data related to it, and then a doc_uploads related to the project_documents table.
This way a project can have as many documents your business will ever need and each document can have as many files as it needs.
You could try something like that:
If you still want to keep both tables, your doc_upload table in your example can have two foreign keys and two belongsTo() Laravel Model declarations without conflicts (it's not a marriage, it's an open relationship).
Or you could use Polymorphic Relations to do the same thing, but it's an anti-pattern of Database Design (because it'll not ensure data integrity on the database level).
For a good reference about Database Design, google for "Bill Karwin" and "SQL Antipatterns".
This guy has a very good Slideshare presentation and a book written about this topic - he used to be an active SO user as well.
ok.
I have a suggestion..you don't have to have such a tight coupling on the doc_upload references. You can treat this actually as a stand alone table in your model that is not pegged to a single entity.. You can still use the ORM to CRUD your way through and manage this table..
What I would do is keep the doc_upload table and use it for all up_load references for all documents no matter what table model the document resides in and have the following fields in the doc_upload table
documenttype (which can be the object name the target document object)
documentid_fk (this is now the generic key to a single row in the appropriate document type table(s)
So given a document in a given table.. (you can derive the documenttype based on the model object) and you know the id of the document itself because you just pulled it from the db context.. should be able to pull all related documents in the doc_upload table that match those two values.
You may be able to use reflection in your model to know what Entity (doc type ) you are in.. and the key is just the key.. so you should be able.
You will still have to create a new model Entity for each flavor of project document you wish to have.. but that may not be too difficult if the rate of change is small..
You should be able to write a minimum amount of code to e pull all related uploaded documents into your app..
You may use inheritance by zero-or-one relation in data model design.
IMO having an abstract entity(table) called project-document containing shared properties of all documents, will serve you.
project-brief and project-report and other types of documents will be children of project-document table, having a zero-or-one relation. primary key of project-document will be foreign key and primary key of the children.
Now having one-to-many relation between project-document and doc-upload will solve the problem.
I also suggest adding a unique constraint {project_id, doc_type} inside project-document for cardinal check (if necessary)
As other answers are sort of alluding to, you probably don't want to have a different Model for different documents, but rather a single Model for "document" with different views on it for your different processes. Laravel seems to have a good "templating" system for implementing views:
http://laravel.com/docs/5.1/blade
http://daylerees.com/codebright-blade/

Database Design for Facebook "likes"

New to database design and I was wondering how to efficiently design something like Facebook likes with future scalability in mind.
Let's say you have 3 tables: users, photos and albums.
Let's say a user can like either a photo or an album.
Should I use 1 table for both types of likes?
This would probably mean it would have an user_id, like_type(0-photo, 1-album etc), like_value(the id value of whatever content it is, whether it is photo_id or album_id)?
or have 2 different tables for each likes (ex. photos_likes and albums_likes)?
which would only contain user_id and photo/album_id
I want to make sure that the database design is clean and semi-scaleproof whether we add many more objects in the future(videos, comments, notes, etc) or have a ton of likes.
Thanks!
You could try a inherited table approach see implementing table inheritence for more indepth detail.
But essentially it works just like inheritence in code, you have a base table 'Like' and then tables which 'inherit' from it 'CommentLike', 'PhotoLike' etc.
See attached diagram for a quick mockup.
Two different tables. This way if you ever have an object that you want to add likes to later you can just make a new table "object_likes" and store the likes there.
If you wanted to store them all in one table, you would need a type table, which would store all the types of objects, and in your like table you would have to reference the type_id. This would let you add types later.
To me the first method is much better.

Efficient way to store a dynamic questionnaire?

In reference to this question, I am facing almost the same scenario except that in my case, the questions are probably static (it's subject to change from time to time, and I still think it's not a good idea adding columns for each question, but even I decided to add, how should the answers be specified/retrieved from), but the answers are in different types, for examples the answer could be yes/no, list-items, free text, list-items OR free text (Other, Please specify), multiple-selectable-list items etc.
What would be an efficient way to implement this?
Shimmy, I have written a four-part article that addresses this issue - see Creating a Dynamic, Data-Drive User Interface. The article looks at how to let a user define what data to store about clients, so it's not an exact examination of your question, but it's pretty close. Namely, my article shows how to let an end user define the type of data to store, which is along the lines of what you want.
The following ER diagram gives the gist of the data model:
Here, DynamicAttributesForClients is the table that indicates what user-created attributes a user wants to track for his clients. In short, each attribute has a DataTypeId value, which indicates whether it's a Boolean attribute, a Text attribute, a Numeric attribute, and so on. In your case, this table would store the questions of the survey.
The DynamicValuesForClients table holds the values stored for a particular client for a particular attribute. In your case, this table would store the answers to the questions of the survey. The actual value is stored in the DynamicValue column, which is of type sql_variant, allowing any type of data - numeric, bit, string, etc. - to be stored there.
My article does not address how to handle multiple-choice questions, where a user may select one option from a preset list of options, but enhancing the data model to allow this is pretty straightforward. You would create a new table named DynamicListOptions with the following columns:
DynamicListOptionId - a primary key
DynamicAttributeId - specifies what attribute these questions are associated with
OptionText - the option text
So if you had an attribute that was a multiple-choice option you'd populate the drop-down list in the user interface with the options returned from the query:
SELECT OptionText
FROM DynamicListOptions
WHERE DynamicAttributeId = ...
Finally, you would store the selected DynamicListOptionId value in the DynamicValuesForClients.DynamicValue column to record the list option they selected (or use NULL if they did not choose an item).
Give the article a read through. There is a complete, working demo you can download, which includes the complete database and its model. Also, the four articles that make up the series explore the data model in depth and show how to build a web-based (ASP.NET) user interface for letting users define dynamic attributes, how to display them for data entry, and so forth.
Happy Programming!
This may not fit you exactly, but here's what i've got at my part-time job.
I have a questions table, an answers table, and a survey table. For each new survey i crate a survey build (because each survey is unique, but questions and answers are repeated a lot). I then have a respondent table that contains some information about the respondent (and it also links back to the survey table, forgot that in the diagram). I also have a response table that links the respondent and the survey build. This probably isn't the best way but it's the way that works for me, and it works pretty fast (we're at about 1mill+ in the response table and it handles like a dream).
With this model i get reusable questions, reusable answers (a lot of our questions use "Yes" and "No"), and a rather slim response table.

Does allowing a category to have multiple parents make sense? Are there alternatives?

Short question: How should product categories that appear under multiple categories be managed? Is it a bad practice to do so at all?
Background info:
We have a product database with categories likes this:
Products
-Arts and Crafts Supplies
-Glue
-Paper Clips
-Construction Paper
-Office Supplies
-Glue
-Paper Clips
Note that glue and paper clips are assigned to both categories. And although they appear in two different spots in this category tree, they have the same category ID in the database. Why? Two reasons:
Categories are assigned attributes - for example, a paper clip could have a weight, a material, a color, etc.
Products assigned to the glue category are displayed under arts and crafts and Office Supplies. Which is to be expected - they're the same actual category ID in the database.
This allows us to manage a single category and it's attributes and assigned products, but place it at multiple places within the category tree.
We are using the nested set model, so the db structure we use to support this is:
Category
----------
CategoryID
CategoryName
CategoryTree
------------
CategoryTreeID
CategoryID
Lft
Rgt
So there's a 1:M between Category and CategoryTree because there can be multiple instances of a given category within the category tree.
Is there a simpler way to model this that would allow a product category to display under multiple categories?
I don't see anything wrong with this as long as it is true that all Glue is appropriate for both Office Supplies and craft supplies.
What you have is a good way, though why not simplify the 2nd table like so:
Category
ID
Name
SubCategory
ID
CategoryID
SubCategoryID
Though for the future I would beware of sharing child categories between the two root categories. Sometimes it is better to create a unique categorization of products for consistency, which is easier to manage for you and potentially easier to navigate for the customer. Otherwise, you have the issue that if you're on the Glue page coming from office supplies, then do you show the other path as well? If not, you will have two identical pages, except for the path, which is an issue for SEO. If you do, then the user may get confused.
The most famous example of this is Google Mail, where the classification is done this way. Google is famous for the usability of their products ...
I believe other words are preferable to the "parent" word, that actually suggest only XToOne relationship...
Maybe you could say that a Product as many Categories, so the relationship would be ManyToMany. And only the display would starts with Categories to reach the Products...
This would highlight a problem : if you don't limit the number of categories, and you display the categories with sub-categories and so on, you could end up with:
a huge categories and product list, with many many duplications
a big depth (probably unreadable)
The interesting part is highlighting the problem, then to imagine a solution that is fine for the end-user.
It may well be necessary for a category to have multiple parents. However, no matter what parent you found a category under, its subcategories should remain the same.
I've seen real systems that implemented precisely this logic and worked fine.
edit
To answer your question, I don't think the model I'm suggesting is as restrictive as you imagine. Basically, a given branch of the tree may be found under more than one parent branch, but wherever it is found, it has the same children. Nothing about this prevents you from cherry-picking some children of one branch and also making them children of another.
So, for example, you could include the glues category under both office supplies and hobby supplies, and if you added "Crazy Glue (Suppository Edition)" under glues, it would show up in both. If you have items that might be grouped together logically but need to be separated by their use, you can still do that. You might put mucilage and paste under the category of hobby adhesives, which goes under the hobby root, but not under the office root. Or you could do that and simultaneously have a combined category that's used internally by your buyers. What you can't do is forget to include that new type of glue in all of the relevant categories once you've added it wherever it belongs in your business model ontology.
In short, you lose very little with this restriction, but gain a bit of structure to help avoid the problem of having to manage each item individually.
edit
Assuming I've made a convincing case for the model itself, there's still the issue of implementation. There are lots of options, but here's one way to go:
There is a CatalogItem table containing a synthetic primary key, the label, optional description/detail text, and an optional SKU (or equivalent). You then have a many-to-many CatalogItemJoin with child and parent ID's, both sides constrained to CatalogItemTable.
An item that appears as a parent is a category, so it should not have a SKU. An item that appears only as a child is a product, so it should have a SKU. It's fine for any item to have more than one parent; that just means that it's in multiple categories. Likewise, there's no problem with multiple children per parent; that would be the typical case of a category with a few products in it. However, given a category's ID, its children will be the same regardless of what parent category led you there. The other constraint is that you'll want to avoid loops.

Resources