8

Phoenix フレームワークは、Railsに見られるようなコールバック フィルターのタイプを採用していますか? before_create変更セットを検証できることはわかっていますが、 、 、 before_saveなどのアクションを実装する方法を探していますafter_commit

4

2 に答える 2

13

Ecto 2.0 から、コールバックは完全に削除されました。

では、今すぐコールバックを処理する方法は?. ここに2つの方法があります

before_コールバックには、Changeset 自体を使用できます。コールバックが削除された理由の 1 つは、チェンジセットで十分な多くの場合、多くの開発者がコールバックに依存していたためです。したがって、必要な関数を変更セットに適用するだけです。

def changeset(post, params \\ :empty) do
  post
  |> cast(params, @required_params, @optional_params)
  |> validate_length(:title, min: 3)
  |> validate_length(:metadata, min: 3)
  |> implement_a_before_callback
end

def implement_a_before_callback(changeset)
   #Apply required actions and return Changeset
end

もう 1 つの方法は、Ecto.Multiを使用して複数のリポジトリ操作をグループ化することです。ドキュメントから

Ecto.Multi は、(単一のデータベース トランザクションで) 一緒に実行する必要がある操作をパックすることを可能にし、キューに入れられた操作を実際に実行せずに内省する方法を提供します。各操作には一意の名前が付けられ、その結果を識別したり、障害が発生した場合に障害の場所を特定したりするのに役立ちます。したがって、データ関連の操作のグループを一度に実行したい場合はいつでも、とコールバックMultiの両方をここで置き換えることができます。before_after_

例は

  # In defmodule Service
  def password_reset(account, params) do
    Multi.new
    |> Multi.update(:account, Account.password_reset_changeset(account, params))
    |> Multi.insert(:log, Log.password_reset_changeset(account, params))
    |> Multi.delete_all(:sessions, assoc(account, :sessions))
  end

を使用して実行します

result = Repo.transaction(Service.password_reset(account, params))

データ関連のクエリを実行する必要があり、電子メールの送信などの他のタスクを実行しないことを覚えておく必要があります。そのためには、結果に対して単純にパターン マッチを行い、適切なアクションを実行できます。トランザクションが成功した場合はメールを送信し、失敗した場合はエラー メッセージを表示します。

case result do
  {:ok, %{account: account, log: log, sessions: sessions}} ->
    # Operation was successful, perform actions like sending a mail
  {:error, failed_operation, failed_value, changes_so_far} ->
    # One of the operations failed. Raise error message
end

ソース:

于 2016-06-26T14:44:20.260 に答える
13

Ecto は: https://hexdocs.pm/ecto/#!Ecto.Model.Callbacks.html

これらは Rails のものとは見た目が異なります: 変更セットを受け取って返す必要があり、データの一貫性のために使用する必要があります (電子メールの送信などには使用しないでください)。

于 2015-04-27T20:54:19.717 に答える