我想问一下如何在模型类上创建动态属性。假设我有一个像下面的代码这样的表结构。
Schema::create('materials', function (Blueprint $table) {
$table->increments('id');
$table->string('sp_number');
$table->string('factory');
$table->text('dynamic_fields')->comment('All description of the material will saved as json');
$table->timestamps();
});
我的表结构中有一列名为“ dynamic_fields”的列,该列将包含字段的JSON字符串。下面是JSON结构的示例。
[
{
"name":"COLOR WAY",
"value":"ASDFF12"
},
{
"name":"DESCRIPTION",
"value":"agg2sd12"
},
{
"name":"REF NUM",
"value":"121312"
}
]
因此,我想从动态字段(例如“ COLOR WAY”)访问字段。 在我的模型中,我想像这样访问动态字段上的“ COLOR WAY”字段
$material->color_way;
有人可以告诉我该怎么做吗? 对不起,我的英语。
答案 0 :(得分:1)
尝试在模型中使用此代码:
protected $casts = [
'dynamic_fields' => 'array',
];
public function setAttribute($key, $value)
{
if (!$this->getOriginal($key)) {
$this->dynamic_fields[$key] = $value;
}
parent::setAttribute($key, $value);
}
public function getAttribute($key)
{
if (!$this->getOriginal($key)) {
return $this->dynamic_fields[$key]
}
parent::getAttribute($key);
}
答案 1 :(得分:0)
如果您知道提前只有某些动态字段,则可以选择为其创建访问器方法。例如,您可以将其添加到模型中:
this.props.switchLanguage
这将允许您执行以下操作:
// Dynamic fields must be cast as an array to iterate through them as shown below
protected $casts = [
'dynamic_fields' => 'array'
];
// ...
public function getColorWayAttribute()
{
foreach ($this->dynamic_fields as $field) {
if ($field['name'] === 'COLOR WAY') {
return $field['value'];
}
}
return null;
}
或者,如果您的$colorWay = $material->color_way;
的组合不受限制,则可能有很多组合,或者您希望有更大的灵活性来添加更多并可以访问它们,则可以覆盖{ {1}}是Laravel模型类的方法。
dynamic_fields
此方法调用Laravel的getAttribute
的实现,该实现首先检查您是否定义了实际属性,或者是否为属性定义了访问器(如我的第一个建议),然后检查是否存在以下方法:在基础模型类上使用该名称,然后如果定义了该名称,则最后尝试加载一种关系。
当每种方法都失败时(返回// Dynamic fields must be cast as an array to iterate through them as shown below
protected $casts = [
'dynamic_fields' => 'array'
];
// ...
public function getAttribute($key)
{
$attribute = parent::getAttribute($key);
if ($attribute === null && array_key_exists('dynamic_fields', $this->attributes)) {
foreach ($this->dynamic_fields as $dynamicField) {
$name = $dynamicField['name'];
if (str_replace(' ', '_', mb_strtolower($name)) === $key) {
return $dynamicField['value'];
}
}
}
return $attribute;
}
),我们然后检查模型中是否有getAttribute
属性。如果存在,我们将遍历每个动态字段(假设您的null
被强制转换为dynamic_fields
),然后将定义的动态字段的名称转换为小写并用下划线替换空格。然后,我们最终检查一下我们刚派生的名称是否与提供的键匹配,如果匹配,则返回该值。如果没有,则将返回原始的dynamic_fields
,即array
。
这将使您能够获取任何动态字段,就像它们在类中被定义为属性一样。
$attribute
请注意::我尚未测试此代码,可能存在一两个问题。尝试一下,看看它是否对您有用。另外请注意,这仅适用于获取动态字段,设置它们将需要覆盖另一种方法。
答案 2 :(得分:0)
在此示例中,您可以从动态模型获得动态列。以及它的模型关系
1)首先,您必须在Model中定义一个表Scope。
private $dynamicTable='';
public function scopeDefineTable($query,$tableName)
{
if( $tableName )
{
$this->dynamicTable= $tableName;
}
else
{
$this->dynamicTable= "deviceLogs_".date('n')."_".date('Y');
}
$query->from( $this->dynamicTable );
$this->table=$this->dynamicTable; # give dynamic table nam to this model.
}
public function scopeCustomSelect( $query ,$items=[])
{
$stu_class_col=['id as stu_class_id','std_id']; // Required else retional model will not retun data. here id and std_id is primary key and foreign key.
$stu_doc_col=['id as stu_doc_id','std_id'];// Required else retional model will not retun data. here id and std_id is primary key and foreign key.
foreach ( $items as $col)
{
if( Schema::hasColumn('student_information', $col ))
{
$stu_info_col[]= $col ;
}
elseif ( Schema::hasColumn('student_class',$col))
{
$stu_class_col[]= $col ;
}
elseif ( Schema::hasColumn('student_image',$col))
{
$stu_doc_col[]= $col ;
}
}
// converting array to string for bind column into with relation...
$stu_class_col_string = implode(',',$stu_class_col);
$stu_doc_col_string = implode(',',$stu_doc_col);
return $colQuery = $query->select($stu_info_col)
->with(["student_class:$stu_class_col_string", "studentImage:$stu_doc_col_string"]);
}
使用此方法,您也可以从Rational Model获取数据...
来自控制器
$studentInfo = Student::whereHas("student_class",function($q) use($req){
$q->where("std_session",$req->session_code);
$q ->where("std_class",$req->class_code);
$q ->where("std_section",$req->std_section); })
->customSelect($fields['dataList'])
->get();
here I am not using dynamic Model Scope. only Dynamic SustomSelect scope..