Reputation: 6062
I have a website where users can transform a text document and save it to what I call a field
. One text document can have a dynamic amount of fields, thus making it hard for me to create a relational database design.
Consider below setup.
My model Field.php
have below fields
table.
id | name | type
-----------------------
1 | invoice_no | text
2 | addresses | table
I also have a table where I save the field result for a specific document:
On model Result
I have a $casts
type:
protected $casts = [
'content' => 'array'
];
This is my results
table:
id | field_id | document_id | content
-------------------------
1 | 1 | 32 | #81724
2 | 2 | 32 | [{"0": "Parkway", "1": "Broadway"}, {"0": "Avenue St.", "1": "Main St."}]
The data from the table is simply being read from a .json
file.
Now ultimately, when all fields for a specific document (in this case 32
) is entered in my database, I would like to send a webhook with the field data, such as:
{
"invoice_no":"#81724",
"addresses": [{
"0": "Parkway",
"1": "Broadway"
},{
"0": "Avenue St.",
"1": "Main St."
}]
}
So above is what I have visioned - but I am not sure if this is the best approach?
$casts
on my Model returns the content
as an array - but as you can see for results.content
, it can be both a string and an array.JSON
type, if I also want to store strings.Would it make more sense to have two columns on the results
table for the content, so it becomes:
id | field_id | document_id | text | array
----------------------------------------------
1 | 1 | 32 | #81724 | NULL
2 | 2 | 32 | NULL | [{"0": "Parkway", "1": "Broadway"}, {"0": "Avenue St.", "1": "Main St."}]
Upvotes: 0
Views: 238
Reputation: 364
The first approach is fine, you need to override the getCastType method as mentioned as an answer for the following question Laravel 5 Eloquent, How to set cast attribute dynamically. So you can adopt different types. For the field data type depends on the maximum expected length, so it may be either a Varchar
or Text
(assuming that all data types you store in this field are text based)
assuming that you expecting two types string
and table
, and you want the table
type to be cast to array
, you may override the getCastType
method as following:
protected function getCastType($key) {
if ($key == 'content' && !empty($this->field->type)) {
switch($this->field->type) {
case 'table':
return 'array';
break;
case 'string':
return 'string';
break;
default:
return parent::getCastType($key);
}
} else {
return parent::getCastType($key);
}
}
and to be able to get access to the field type using $this->field->type
, you need to implement the relationship in the result model as following:
public function field() {
return $this->belongsTo('App\Field');
}
All the Best
Upvotes: 1
Reputation: 584
By far the easiest and ugliest way to do this is to add a BLOB column to your database (tables) and just store the JSON there.
What you could do is send the results from the table as arrays to the backend and process it there using []
on the names of your input fields.
Please post how you get the data from the table so I can assist you further and someone will probably tell you how you can get this working.
Upvotes: 0