【问题标题】:Laravel Submodel Of an Model模型的 Laravel 子模型
【发布时间】:2021-09-29 10:50:51
【问题描述】:

在我的 Laravel 应用程序中,我需要基本 ORM 模型的子模型,用于我的数据库中特定类型的项目,这些项目在数据库的“类型”列中指定。

在我的基本模型中,我将此覆盖用于函数 newFromBuilder

// OVERRIDES
public function newFromBuilder($attributes = [], $connection = null)
{
    $class = "\\App\\Models\\" . ucfirst($attributes->type);

    if (class_exists($class)) {
        $model = new $class();
    } else {
        $model = $this->newInstance([], true);
    }

    $model->setRawAttributes((array)$attributes, true);
    $model->setConnection($connection ?: $this->getConnectionName());
    $model->fireModelEvent('retrieved', false);

    return $model;
}

但是由于某种原因,当我在子模型中调用保存或更新函数时,什么也没有发生 :( 每个子模型都应该使用 fase 模型的保存功能,对吗?有人可以帮我解决保存功能的问题吗?

基础模型:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Carbon;

use App\Models\Devices;
use App\Models\Records;
use App\Models\Rooms;

use App\Helpers\SettingManager;
use App\Types\GraphPeriod;
use App\Types\PropertyType;

class Properties extends Model
{
    protected $fillable = [];
    protected $table = 'sh_properties';
    protected $primaryKey = 'id';

    public $period = GraphPeriod::DAY;

    //OVERIDES
    public function newFromBuilder($attributes = [], $connection = null)
    {
        $class = "\\App\\Models\\" . ucfirst($attributes->type);

        if (class_exists($class)) {
            $model = new $class();
        } else {
            $model = $this->newInstance([], true);
        }

        $model->setRawAttributes((array)$attributes, true);
        $model->setConnection($connection ?: $this->getConnectionName());
        $model->fireModelEvent('retrieved', false);

        return $model;
    }


    //NEW RELATIONS
    public function records()
    {
        return $this->hasMany(Records::class, 'property_id');
    }

    public function latestRecord()
    {
        return $this->hasOne(Records::class, 'property_id')->latestOfMany();
    }

    public function device()
    {
        return $this->belongsTo(Devices::class);
    }

    public function room()
    {
        return $this->belongsTo(Rooms::class);
    }

    public function settings()
    {
        if ($settings = SettingManager::getGroup('property-' . $this->id)) {
            return $settings;
        }
        return false;
    }

    //FUNCTIONS
    public function getLatestRecordNotNull()
    {
        return Records::where("property_id", $this->id)->where("value", "!=", null)->where("value", "!=", 0)->first();
    }

    //Virtual  Values
    use HasFactory;


    //Add Function for mutator for vaue (vith units) and rav value















    public function values()
    {
        $dateFrom = Carbon::now()->subDays(1);

        switch ($this->period) {
            case GraphPeriod::WEEK:
                $dateFrom = Carbon::now()->subWeek(1);
                break;
            case GraphPeriod::MONTH:
                $dateFrom = Carbon::now()->subMonth(1);
                break;
            case GraphPeriod::YEAR:
                $dateFrom = Carbon::now()->subYear(1);
                break;
        }

        return $this->hasMany(Records::class, 'property_id')->whereDate('created_at', '>', $dateFrom)->orderBy('created_at', 'DESC');
    }

    public function getAgregatedValuesAttribute($period = GraphPeriod::DAY)
    {
        $dateFrom = Carbon::now()->subDays(1);
        $periodFormat = "%Y-%m-%d %hh";

        switch ($this->period) {
            case GraphPeriod::WEEK:
                $dateFrom = Carbon::now()->subWeek(1);
                $periodFormat = "%Y-%m-%d";
                break;
            case GraphPeriod::MONTH:
                $dateFrom = Carbon::now()->subMonth(1);
                $periodFormat = "%Y-%m-%d";
                break;
            case GraphPeriod::YEAR:
                $dateFrom = Carbon::now()->subYear(1);
                $periodFormat = "%Y-%m";
                break;
        }

        $agregatedData = Records::select(['value', 'done', 'created_at'])
            ->selectRaw("DATE_FORMAT(created_at, ?) as period", [$periodFormat])
            ->selectRaw("ROUND(MIN(value), 1) AS min")
            ->selectRaw("ROUND(MAX(value), 1) AS max")
            ->selectRaw("ROUND(AVG(value), 1) AS value")
            ->where('property_id', $this->id)
            ->orderBy('created_at', 'DESC')
            ->groupBy('period');

        $agregatedData->where('created_at', '>=', $dateFrom);
        return $agregatedData->get();
    }

    public function last_value()
    {
        return $this->hasOne(Records::class, 'property_id', 'id')->latest();
    }




    //Virtual  Values


    //Virtual  Values
    /**
     * Minimum value that property had in past.
     *
     * @return int
     */
    public function getMaxValueAttribute()
    {
        if ($this->records) {
            return $this->records->max("value");
        }
        return false;
    }

    /**
     * Maximum value that property had in past.
     *
     * @return int
     */
    public function getMinValueAttribute()
    {
        if ($this->records) {
            return $this->records->min("value");
        }
        return false;
    }


    /**
     * step value used to increment each value usually used for range type or thermostats, graphs also.
     *
     * @return int
     */
    public function getStepValueAttribute()
    {
        if ($step = SettingManager::get('step', 'property-' . $this->id)) {
            return ($step->value < 1 ? $step->value : 1);
        }
        return false;
    }

    /**
     * max set value for prop
     *
     * @return int
     */
    public function getMaxValueSettingAttribute()
    {
        if ($step = SettingManager::get('max', 'property-' . $this->id)) {
            return ($step->value > 1 ? $step->value : 1);
        }
        return false;
    }

    /**
     * min set value for prop
     *
     * @return int
     */
    public function getMinValueSettingAttribute()
    {
        if ($step = SettingManager::get('min', 'property-' . $this->id)) {
            return ($step->value > 1 ? $step->value : 1);
        }
        return false;
    }


    public function setValue($value)
    {
        $record                 = new Records;
        $record->value          = $value;
        $record->property_id    = $this->id;
        $record->save();
        return true;
    }
}

子模型

namespace App\Models;

use App\Models\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Humi extends Properties
{
    protected $historyDefault = 90;
    protected $unitsDefault = "%";
    protected $iconDefault = "";

    public function save(array $options = [])
    {
        // before save code 
        $result = parent::save($options); // returns boolean
        // after save code
        return $result; // do not ignore it eloquent calculates this value and returns this, not just to ignore
    }
}

提前感谢您的任何建议或帮助:)

【问题讨论】:

    标签: php laravel eloquent


    【解决方案1】:

    当使用$this-&gt;newInstance() 函数创建新实例时,$model-&gt;exists 属性设置为 true。我认为你也应该在你的 if 语句中做同样的事情。否则它将尝试在数据库中创建新记录。

    最好也复制函数的其余部分以避免它可能导致的任何其他问题。

    if (class_exists($class)) {
        $model = new $class();
    
        // Important
        $model->exists = true;
    
        $model->setTable($this->getTable());
    
        $model->mergeCasts($this->casts);
    } else {
        $model = $this->newInstance([], true);
    }
    

    【讨论】:

    • 您好,感谢您发布您的建议,它几乎可以按要求工作:) 但是我无法在 ech 子模型不同的公共函数 getValueAttribute( $value) 知道怎么做吗?
    猜你喜欢
    • 1970-01-01
    • 2018-10-27
    • 2021-06-05
    • 2020-02-29
    • 2020-09-10
    • 1970-01-01
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多