Support Forum
Support › MB Custom Table › Questions/ feedback regarding custom tables/ relationships
So I specifically bought your plugin because it has native support for custom tables/ many to many relationships which ACF doesn't have. I can't stand word presses way of storing everything in post and post meta. But then I read the docs, and I am now confused.
I do not understand WordPress's way of handling things. In Laravel, creating relationships and tables is very easy. WordPress, not so much. And I really don't want to store many large functions in one big file, yet I'm not sure how to structure files to separate each model.
With that said, I am trying to understand what I need to do to work with custom tables with metabox.
First, you have the option to auto create tables, yet you store everything as a text field?
There are many field types that would be obvious so you wouldnt have to do that. Booleans are TinyINT, foreign keys are typically BIT INT, any number or date field will be int or date. So I'm not sure why everything would be TEXT. With that said, if you want to provide flexibility in case there are alternatives to the above, how hard would it be to create a dropdown selector with the needed DB options (nullable, length, type, etc) so that a table can be created properly without having to dig into custom code. This could be in an advanced tab if "Create table" is selected.
2. If we do have to go into custom code, these are the requirements as i understand them.
1- create the table,
ction( 'init', function () {
MB_Custom_Table_API::create(
'my_custom_table', // Custom table name.
[ ...
2. Link fields to table-- Or is this step only if I "use an existing table"?
Regarding this step, I'll assume 'id' is the field key? It confused me at first cause 'id' usually refers to a primary key. But then you also have 'name'? --Is this the key? Then on email you also have type email?
I don't understand what I am entering here. Am I creating the meta boxes, or creating the table? Or what? cause "email" definitely isn't a database field. And if 'id' and 'name' always seem to match, this should be available programmically right (IE as part of the plugin to make the process easier for users who dont code)
Something like `get_fields($fields){
foreach ($fields as $field){
['id'=>$field, 'name'=>ucword($field)]
} `
add_filter( 'rwmb_meta_boxes', function( $meta_boxes ) {
$meta_boxes[] = [
'title' => 'Meta Box Title',
'storage_type' => 'custom_table',
'table' => 'my_custom_table', // Your custom table name
'fields' => [
[
'id' => 'address',
'name' => 'Address',
],
[
'id' => 'phone',
'name' => 'Phone',
],
[
'id' => 'email',
'type' => 'email',
'name' => 'Email',
],
],
];
3. Regarding relationships, I have determined that the POST selection is what I would need for 1:M relationships, while the M:M relationships are handled by the extension, right? IE, it should be creating a foreign_id field in the related table. If a store has items, I'd want to create a post connection to items and then select the items i want connected? How is this stored? In this example, lets assume its not a M:M where an item could be in multiple stores.
If so, this might be worth mentioning in the relationships docs.
This is primarily what I would be using repeater fields to do. Or in my case, i have one model where I need to define "alternative names" which I had set as a repeater. But those names need to be searchable to return the model, so I'm not sure how a non quarriable "group/ repeater" field would help. I have these names set as an separate model in my laravel version, but I'm not sure how WordPress would handle this, but it would again depend on the model_id foreign key being available.
I have many related models that I need to figure out with has_many(1:M) or many_to_many (M:M) relationships. Some many to many also have additional data that needs to be attached. So is there currently a method of attaching additional fields to the relation table you all created? A job and employee relationship would have fields such as pay, position, etc that would need to be determined.
4. I saw a post I believe around 2018 regarding wp-all-import support into custom tables. Has this been addressed yet, or perhaps a native solution? If the custom tables can be arranged properly, I can also just import directly via phpmyadmin or other standard solutions, but I've got to get the table structure to be correct and not revert back to "text" fields when I manually change it.
5. I sure hope this plugin works with bricks builder, otherwise all of this will be unusable.
Anyway, I do hope I can get this figured out, cause I've got a lot of data that needs to be properly organized. Thanks
Hello,
1. If you are using the builder to create custom fields and custom table, we have a note for this case, the data type is TEXT
to compatible with the most of field data: https://docs.metabox.io/extensions/mb-custom-table/#getting-started
If you select the option Create table automatically, the plugin will attempt to create the table for you. Once it's done, you'll see the custom table in your database, which has columns that match your custom field IDs, each column per field ID. To make the data compatible with the field data, the plugin uses data type TEXT for all columns.
2. The custom table created by Meta Box will have one ID column which is the post ID and the other columns are the field IDs. The column name must be matched with the field ID if you use the existing custom table. Read more in the documentation https://docs.metabox.io/extensions/mb-custom-table/#notes
3. The relationship value is saved to a custom table wp_mb_relationships, you can create a relationship between post and page then check the data in that table.
Also, the relationship does not work with the custom model created by the custom table https://docs.metabox.io/extensions/mb-custom-table/#custom-models
4. I'm not sure if the custom table can work with WP All Import, you can follow this topic https://wordpress.org/support/topic/import-custom-fields-into-custom-table/
or contact them to get further information.
You can export and import the custom table by using PHPMyAdmin, I think it is easier to do.
5. Bricks builder maintains compatibility with Meta Box, if you have any questions with Bricks, please contact them to get further information. Please read more here https://docs.metabox.io/compatibility/
So since you really did not address any of the concerns and point of confusion regarding the DOCS which was the point of this prompt, I will try to clarify. IE, I have read the docs, but I have questions regarding the docs. So linking back to the docs in which I have questions, is not the answer I need.
1. I am aware you use TEXT for everything.
I'm also aware WORDPRESS stores basically everything into the database and then compiles it into working code.
With that said, My FEATURE REQUEST is that you all think about improving usability within your plugin by having an advanced tab that allows people to change data structures. A column for data type, an input for size, a checkbox for nullable data and such. You know, like how php my Admin does it or any other database program.
IF no data is changed, then you default to TEXT as you have it. But as I said before, there are many fields that will have obvious data types, and a little thought on your part would save people the hassle and improve performance.
SWITCHes are always Boolean. numbers are INT
if someone set a limit of characters on a field, why not create a corresponding varchar or char? Again you can use TEXT default, but please provide a UI option for people to choose what works for their app without having to dive into the mysteries of WordPress custom code.
Your plugin has a bit more native options than ACF, so if you can make it more user friendly, you would surpass ACF in sales for the sole fact you have that native database and relationships to by pass WordPress's ugly way of data storage. I'm trying to help you make it more user friendly as right now, there are some confusing aspects.
1A This is where I am confused
After I create the table with
register_activation_hook( __FILE__, function() {
MB_Custom_Table_API::create( 'my_custom_table', [
'address' => 'TEXT NOT NULL',
'phone' => 'TEXT NOT NULL',
'email' => 'VARCHAR(20) NOT NULL',
], [ 'email' ] );
} )
<strong>
Do I then also need to link the table to the fields? Or is that step only if I create a table outside of WordPress? </strong>
And if I am linking the fields I created in the UI, to that custom table, is that where this "connecting custom fields to custom table" part comes into play? cause it sure seems like the code presented in the docs is creating the fields opposed to using the ones already made. I can understand if i need to map 'field_names=>'column_name' (though this should be automatic if name===column), but I'm not understanding why I need the other field information to create a link to a properly structured table if I already created the fields in the UI.
I need this to be as seamless as possible, cause if I transfer my whole project to wordpress with a fully normalized set up, this is what I would be working with. <a href="https://boss21784.imgur.com/all#3" rel="noopener" target="_blank">database</a>
Your plugin is helping me get there, but there's still some things I need to clarify and figure out how to make them work.
3. Im also aware of the relationship docs. That created table is fine for most cases. M:M with a polymorphic set up.
My first question was regarding 1:M, which is handled by the POST field, and stored as an array in the DB. While not ideal, I can live with it as long as i can reference the ID's
My problem however, is if I need to reference a field of that related post. How do I do this?
<strong>Sample: Equipment has vendors</strong> vendors has a URL to their website. So on the equipment page, i need to loop through the "where_to_buy" and then instead of using post_url, i need the vendor_url as the link. I'm not sure if its something within bricks builder giving me trouble, or if i'm coding it wrong, but I cannot get the link to display properly.
<?php $post_ids = rwmb_meta( 'where_to_buy' );
foreach ($post_ids as $post_id):
?>
<a>"><?= get_the_title( $post_id ); ?></a><br/>
<?php endforeach ?>
3A-- also regarding the ALT names, if these are stored in a serialized array, how would I reference them in search, so that my search would be Select post_title FROM POST or "alternative_name" FROM model.alt_name so that the same record would be displayed in search results. IE if i had this on a user table, I might want to search by the user name or a nick name, or perhaps a maiden name. My sample is from a hobby table in which a hobby could be known as several things. So those alternative names need to be searchable as if they were the post title itself
3B: Finally regarding the relationship inputs. That is also a bit confusing the way you have it set up.
First, please define reciprocal relationship or use a different wording within the plugin UI so people dont have to reference the docs or a dictionary to figure out what this is. Just add this same line " a relationship between items of the same type. If you choose this, make sure you set the settings for the "From" and "To" sides the same." And maybe add an example "IE. USER to USER relationship"
BUT SECOND, and most confusing is in which field I need to place my labels.
If i have my equipment to Vendors table in From/ To respectively,
If I'm picking the Equipment post type as a reference, I'd expect that the corresponding metabox, and column labels would be Equipment, yet its the opposite. (even if the equipment box gets added to the vendor edit screen, the labels should be consistent to avoid confusion.)
And perhaps your set up is technically right, but if i have to spend 5 minutes thinking about what input needs to go in which box to get the correct label, then it needs to be reworked.
Maybe instead of FROM: TO: You can use model 1, model 2. the models need to be referenced, and explained, or with a sample text that says, Title (1): Connection to model 2 (IE Vendor)
or under Metabox From settings, "What you see on the TO model" and To Settings: "What you see on the FROM MODEL"
It just needs to be made clearer somehow cause even trying to explain the issue here, I'm having to spend considerable time figuring out what goes where.
Finally - Another IMPROVEMENT REQUEST
If the selector could have an option to choose from the various select types your plugin offers, that would also improve things. Listing the vendors out in the default taxonomy view so its a one click selection opposed to 3, would be ideal, but the SELECT 2 Interface would also work better than the current method.
Anyway, sorry for the long posts. Just trying to improve usability and understand what I need to do to make my app work.
Hello,
1. Thanks, I will inform the development team to consider supporting an option to set the data type manually in the builder.
1A. Yes, the code is the step to create the custom table. You will need to link the custom fields to the table. In the builder, you need to enable option "Save data in a custom table" and add the table name to the option below, and don't enable option "Create table automatically", screenshot https://monosnap.com/file/z8Zg1W3PfLoLFFGR2ihvibBdqnnAhb
3. You can follow the documentation https://docs.metabox.io/functions/rwmb-meta/
to get the post meta (field value) based on the post ID. For example:
$post_ids = rwmb_meta( 'where_to_buy' );
foreach ($post_ids as $post_id) {
echo rwmb_meta( 'vendor_url', '', $post_id );
}
3A. I'm not sure what is the search you want to use but it needs to have some custom code to create an SQL query in the database and it's beyond the scope support of Meta Box. Meta Box supports inputting values in the backend and outputting the value in the frontend.
3B. Thanks for your feedback. I will inform our development team to improve the documentation and UI for easier to use.
Final: What is the selector or field type you are mentioning? Do you mean the default select field of Object type and Post type when creating the relationship?
Thanks, the updated where to buy code did the trick. I figured there was probably an easier way to handle theat.
Regarding the selector. In you POST field type you have the option select field type as select, select Advanced (which I believe is the SELECT2 interface) Select tree, and so forth.
I would like to just extend those same options to the relationship designation. Cause as i said, the current form field requires 3 clicks to select the desired relationship. Select Advance might be 2 clicks but takes up less real estate and prevents selecting a relationship twice. and a checklist or radio list would be one click and maybe some scrolling.
Also your current system allows the same entries to be selected multiple times which is not good. Meaning you can have an Model 1: Related Model B, multiple times which I believe would create some repeated outputs or integrity problems.
In my opinion though, all relationship items should be within the custom field selection.
I created a mockup of how I believe my suggestions (and a few others) could be implemented. I strongly believe if you are able to get this database solution figured out and user friendly, you will gain a lot of new subscribers for all the developers who do not use WordPress due to the crazy data structure.
Hello,
1. You can use the code to change the default field type (select_advanced) of the relationship field. For example:
function my_func123() {
MB_Relationships_API::register( [
'id' => 'job-to-post',
'from' => [
'object_type' => 'post',
'post_type' => 'my-job',
'field' => [
'field_type' => 'checkbox_list',
]
],
'to' => [
'object_type' => 'post',
'post_type' => 'post',
'field' => [
'field_type' => 'select',
]
],
] );
}
2. Thanks, I will forward your design to our development team to take a look.
Hi, thanks for your assistance so far. My internet hasnt been working that well so i haven't had the chance to work much on this project, But in regard to the above code. that seems to be a manual way of creating a relationship. You have a nice UI (with some issues already discussed) but I would like to use it as I don't want to clutter a function file for every relationship just cause I want a different field type by default. I'll gladly add a single function like SetDefaultRelation {'field_type'=>'select_advanced'} but I'm not sure what needs to be overwritten. (this needs to allow multi selection)
Can you please provide the code to change the default field_type to select_advanced for ALL relationships. I can't figure out your code to override the setting.
As stated before, Having to click new for each new record is SLOW for models with many pairing. (If there is a way to Accept ENTER to create a new line on any repeater, that would be ideal.) And It would create data problems as you have no check for already selected pairing.
Thanks