使用多个型号时保持功能干燥

时间:2013-12-22 11:37:59

标签: php laravel-4

我目前有一系列库存系统模型,其中一个模型是一个处理向产品添加变体的函数:

public function addVariant($options, $values = array())
{
    // Clone parent
    $variant = $this->replicate();

    // Update values for the cloned item
    if (count($values)) $this->updateValues($variant, $values);
    $variant->save();

    // Add options
    foreach ($options as $option) InventoryItemOption::addVariation($variant, $option);
}

private function updateValues($variant, $values)
{
    // Loop through the values and if the key exists, update the value
    foreach ($values as $key => $value) if (isset($variant->$key)) $variant->$key = $value;

    return $variant;
}

作为addVariant的一部分,它会在addVariation()中通过InventoryItemOption添加实际变体:

public static function addVariation($item, $variation)
{
    $option = new InventoryItemOption;
    $option->item_id = $item->id;
    $option->option_id = $variation;
    $option->save();

    return $option;
}

如何以干燥的方式处理,不一定在此示例中,而是跨越多个模型的任何功能。这是辅助函数应该出现的地方吗?

我想验证updateValues()之后传递的数据,如果它没有验证则返回失败,但我还要验证通过addVariation()添加的每个变体是否有效并存在于数据库,我可以通过使用Validator来做到这一点但是我不确定一个模型是否应该首先调用另一个模型。

我不想写多个函数来做同样的事情来添加变体,因此它需要集中在某处,但是当我编写更多函数时,我注意到这个交叉模型函数调用正在发生越来越多。

1 个答案:

答案 0 :(得分:0)

Laravel可以轻松保持干爽,但需要一点创造力。您可以将BaseModel置于其间:

,而不是您的模型扩展Eloquent
abstract class BaseModel extends Eloquent {
    public function write($input, $key = 'id')
    {
        // Instantiate object
        if (! empty($input[$key]))
            $resource = $this->findOrFail($input[$key]);
        else
            $resource = $this;

        // Fill object with user input using Mass Assignment
        $resource->fill($input);

        // Save data to db
        if (! $resource->save())
            App::abort(500, 'Could not save resource');

        return $resource;
}

class Variant extends BaseModel {
}

然后在您的变体模型(或任何其他模型)上,您可以设置protected $fillable属性。要在模型上插入/更新值,您只需从控制器中调用以下内容:

// Instantiate Model
$resource = new Variant;

// Write data to Model
$transaction = $resource->write($input);

另外;您可以对BaseController使用相同的技术,因此您的控制器也将保持干燥状态。