正しい方法を見つけることは私にとって困難だったので、以下であなたが私が作ったベストプラクティスを見つけることができました。楽しんで、必要に応じて英語を修正し、私が間違っていると言ってください。:)
編集: ...そして、私はいくつかの面で間違っていたことがわかりました。だから、ラファエルの答えが私をもっと理解するのを助けてから、元の投稿を更新しました。彼に感謝!
以下で使用される概念:
これらの概念に慣れていれば、以下のコードと説明を理解しやすくなります。
- インジェクションの依存関係(
$this->variableコード内のすべての変数がインジェクトされるため) - サービス契約とリポジトリ
- 工場
コンテキスト:
より多くのコンテキストを持つために、モジュールが正しく構築されていると想像してください:
- 方法を含むブロッククラスCustomBlock
getCustomModel($id)、 - このメソッドは、paramで渡されたIDに基づいてCustomModelオブジェクトを返します。
- CustomModelタイプは、モデルに対応します
\Vendor\Module\Model\CustomModel - このモデルには、そのリソースモデル(
\Vendor\Module\Model\ResourceModel\CustomModel)が付属しています - およびそのリポジトリ(
\Vendor\Module\Model\CustomModelRepository)を使用します。
質問:
- すべてがCustomModelオブジェクトをロードできるようにするベストプラクティスは何ですか?
load()このメソッドは廃止されているため、CustomModelオブジェクトからを使用することはできません。
良い習慣は、CustomModelサービス契約を使用する必要があることです。サービスコントラクトは、データインターフェイス(CustomModelInterfaceなど)とサービスインターフェイス(CustomModelRepositoryInterfaceなど)です。だから私のブロックは次のようになります:
/ ** @var SlideRepositoryInterface * /
保護された$ slideRepository;
/ **
* CustomBlockコンストラクター
* ...
* @param CustomModelRepositoryInterface $ customModelRepository
* ...
* /
パブリック関数__construct(
...
CustomModelRepositoryInterface $ customModelRepository
...
){
$ this-> customModelRepository = $ customModelRepository;
}
パブリック関数getCustomModel($ id){
return $ this-> customModelRepository-> get($ id);
}
まず、CustomModelRepositoryInterfaceオブジェクトをコンストラクターに注入し、getCustomModel()メソッドで使用します。
クラスApi\CustomModelRepositoryInterfaceでは多くはありません。一般的に、基本的なメソッドを宣言します(が、何も違っ行うためにあなたを防ぎます): 、get、getList、save、。delete deleteByIdこのトピックの目的のために、以下はgetメソッド宣言です。
/**
* Get info by id
*
* @param int $id
* @return Data\CustomModelInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function get($id);
わかりましたが、ブロックコンストラクターの依存性注入によってCustomModelインターフェイスが呼び出された場合、コードはどこにありますか?この質問に対する答えを得るには、Magentoにこのインターフェイスを実装するクラスを見つける場所を説明する必要があります。モジュールのetc / di.xmlファイルに、次を追加する必要があります。
<preference for="Vendor\Module\Api\CustomModelRepositoryInterface" type="Vendor\Module\Model\CustomModelRepository" />
したがって、CustomModelRepositoryInterfaceクラスはサービスインターフェイスです。それを実装する際には、データインターフェイスも実装する必要があります(少なくともVendor\Module\Api\Data\CustomModelInterfaceおよびVendor\Module\Api\Data\CustomModelSearchResultsInterface)。モデルでは、インターフェイスごとVendor\Module\Api\Data\CustomModelInterfaceに<preference ... />行を実装して追加する必要があります。最後に、サービス契約を使用するときはいつでも、mySomethingInterfaceもう考えないでmySomethingください。magentoにdi.xml設定メカニズムを使用させます。
さて、次は何ですか?CustomModelRepositoryInterfaceブロックコンストラクターに注入すると、CustomModelRepositoryオブジェクトが取得されます。CustomModelRepositoryメソッドdeclareを実装する必要がありCustomModelRepositoryInterfaceます。だから私たちはこれを持っていますVendor\Module\Model\CustomModelRepository:
パブリック関数get($ id){
$ customModel = $ this-> customModelFactory-> create();
$ customModel-> load($ id);
if(!$ customModel-> getId()){
throw New NoSuchEntityException(__( 'id "%1"のCustomModelは存在しません。'、$ id));
}
return $ customModel;
}
何をしているの?CustomModel工場のおかげで空のオブジェクトを作成します。次にCustomModel、ロードモデルメソッドを使用してデータをロードします。次に、paramsでid NoSuchEntityExceptionをロードできなかった場合にを返しCustomModelます。しかし、すべてが大丈夫であれば、モデルオブジェクトを返し、人生は続きます。
しかし、すごい...!この例では何ですか?
$customModel->load($id);
load最初と同じ非推奨のメソッドではありませんか?はい、そうです。残念だと思いますが、このload()メソッドにはいくつかのイベントがディスパッチされており、開発者がそれらをリッスンできるため、使用する必要があります(以下のRaphaelの回答を参照)。
将来的には、Entity Managerによって保存されます。新しいMagento 2コンセプトとしては別の話ですが、注目したい場合は、CMSページ(v2.1)のリソースモデルにエンティティマネージャーが既に実装されています。
public function load(AbstractModel $object, $value, $field = null)
{
$pageId = $this->getPageId($object, $value, $field);
if ($pageId) {
$this->entityManager->load($object, $pageId);
}
return $this;
}