laravel 关系方法可以返回null而不是MorphMany关系对象吗?

mv1qrgav  于 2023-01-27  发布在  其他
关注(0)|答案(1)|浏览(141)

我的问题可能更哲学而不是具体的。我使用Laravel 8,我有一个Trait,它被几个类使用,它的一些方法通过考虑对象是否有特定的morphMany关系(这里称为条目)来执行两种不同的计算。这个trait几乎可以用下面的代码实现:

trait MyTrait {
  // Some methods...

  // Entries methods
  abstract public function hasEntries();
  abstract public function entries();

  // Here is a method that depends on entries
  public function computFunc() {
    return $this->hasEntries()
      ? $this->computWithEntries()
      : $this->computWithoutEntries();
  }

  private function computWithEntries() {
    // Perform computation with entries by using entries() relationship...
  }
  private function computWithoutEntries() {
    // Perform computation without entries...
  }

  // Some other methods...
}

显然,具有条目关系的类也在hasEntries()方法中实现了一些条件,以检查当前对象是否存在条目,如以下示例所示:

class ModelA {
  use MyTrait;

  public function entries() {
    return $this->morphMany(Entry::class, 'owner');
  }
  public function hasEntries() {
    return $this->entries()->where([ /* Some condition */ ])->exists();
  }
}

现在我的问题是:对于没有条目关系的类,什么应该返回entries()方法,这意味着不可能/不允许条目表的列 owner_type 等于这些类之一。
下面是这种情况的一个示例(ModelB不能拥有任何条目):

class ModelB {
  use MyTrait;

  public function entries() {
    // Should return null?
    return null;
  }
  public function hasEntries() {
    return false;
  }
}

对于类ModelB的对象,什么值/对象应该返回entries()方法?我很确定返回null而不是关系对象不是正确的做法,对吗?

ffx8fchx

ffx8fchx1#

我想你可以用另一种方法来完成这件事,试试这个:
1.将你的特质分成2个不同的特质(一个用来创建关系,另一个用来检查是否有条目并计算结果)。
1.创建一个包含第二个trait的方法的接口(契约)(只是为了确保这些方法存在于类中),这样您就可以指定返回的值是否应该是布尔值。
这样,你就不会在代码的计算部分有问题了。希望我的答案对你有帮助。
编辑-快速示例:

//EntriesRelationTrait.php
trait EntriesRelationTrait {
    public function entries() {
        return $this->morphMany(Entry::class, 'owner');
    }
}

//ComputeByEntriesTrait.php

trait ComputeByEntries {
    public function computFunc() {
        return $this->hasEntries()
          ? $this->computWithEntries()
          : $this->computWithoutEntries();
    }

    private function computWithEntries() {
      // Perform computation with entries by using entries() relationship...
    }
    private function computWithoutEntries() {
      // Perform computation without entries...
    }
}

//HasEntriesContract.php
interface HasEntriesContract
{
    /**
     * @return bool
     */
    public function hasEntries(): bool; 
    //function type declaration available only after PHP 7.0

}

class ModelA implements HasEntriesContract {
    use EntriesRelationTrait;
    use ComputeByEntriesTrait;

    public function hasEntries(): bool {
        return $this->entries()->where([ /* Some condition */ ])->exists();
    }
}

class ModelB implements HasEntriesContract {
    use ComputeByEntriesTrait;

    public function hasEntries(): bool {
        return false;
    }
}

契约确保创建的函数遵循标准,在本例中,是来自hasEntries方法的布尔响应。

相关问题