我知道可以为各个字段定义访问器和更改器,如下所示:
public function setSomeAttribute($value) {
// set the attribute
}
public function getSomeAttribute() {
// return the attribute}
}
Run Code Online (Sandbox Code Playgroud)
但是,是否可以定义一个将用于所有属性获取和设置的回退方法?
原因是我想动态地将任何空值转换为空值,以保持我的数据库清洁并允许可空字段为空而不是空字符串(如果有更好的方法,请告诉我!)
我正在寻找类似的东西
public function setAttribute($property,$value) {
$this->$property = empty($value) ? null : $value;
}
Run Code Online (Sandbox Code Playgroud)
更新:
感谢Chris Goosey,我找到了一个适合我的解决方案.我扩展了Eloquent模型方法setAttribute,如果它是空的,我将值设置为默认列.我的数据库中通常为null,零或空字符串,因此对我有用!
public function setAttribute($key, $value)
{
// Convert empty values to their default values (e.g. null, zero)
if(empty($value) && $this->getSchema()->hasColumn($key)) {
$value = $this->getSchema()->getColumn($key)->getDefault();
}
parent::setAttribute($key,$value);
}
Run Code Online (Sandbox Code Playgroud)
小智 11
最好的方法可能是扩展Eloquent类覆盖setAttribute和getAttribute方法.
对于所有模型继承这些重写方法,您可能希望创建一个扩展雄辩的类,例如
<?php
class BaseModel extends eloquent {
public function setAttribute($property,$value) {
$this->$property = empty($value) ? null : $value;
}
public function getAttribute($key) {
// Do Stuff
}
}
Run Code Online (Sandbox Code Playgroud)
然后你的所有模型都应该扩展到这个新类,例如
<?php
class User extends BaseModel {
protected $table = 'users';
}
Run Code Online (Sandbox Code Playgroud)
还值得一提的是,您的新方法应该具有旧方法的所有功能以及您的新功能,这就是getAttribute()的样子(Illuminate\Database\Eloquent line 2212):
/**
* Get an attribute from the model.
*
* @param string $key
* @return mixed
*/
public function getAttribute($key)
{
$inAttributes = array_key_exists($key, $this->attributes);
// If the key references an attribute, we can just go ahead and return the
// plain attribute value from the model. This allows every attribute to
// be dynamically accessed through the _get method without accessors.
if ($inAttributes || $this->hasGetMutator($key))
{
return $this->getAttributeValue($key);
}
// If the key already exists in the relationships array, it just means the
// relationship has already been loaded, so we'll just return it out of
// here because there is no need to query within the relations twice.
if (array_key_exists($key, $this->relations))
{
return $this->relations[$key];
}
// If the "attribute" exists as a method on the model, we will just assume
// it is a relationship and will load and return results from the query
// and hydrate the relationship's value on the "relationships" array.
$camelKey = camel_case($key);
if (method_exists($this, $camelKey))
{
return $this->getRelationshipFromMethod($key, $camelKey);
}
}
Run Code Online (Sandbox Code Playgroud)
并且同一文件中的setAttribute看起来像这样(第2338行):
/**
* Set a given attribute on the model.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function setAttribute($key, $value)
{
// First we will check for the presence of a mutator for the set operation
// which simply lets the developers tweak the attribute as it is set on
// the model, such as "json_encoding" an listing of data for storage.
if ($this->hasSetMutator($key))
{
$method = 'set'.studly_case($key).'Attribute';
return $this->{$method}($value);
}
// If an attribute is listed as a "date", we'll convert it from a DateTime
// instance into a form proper for storage on the database tables using
// the connection grammar's date format. We will auto set the values.
elseif (in_array($key, $this->getDates()))
{
if ($value)
{
$value = $this->fromDateTime($value);
}
}
$this->attributes[$key] = $value;
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
6051 次 |
| 最近记录: |