work on steps
This commit is contained in:
		| @@ -5,7 +5,7 @@ defmodule Memex.Pipelines.Pipeline do | ||||
|   use Ecto.Schema | ||||
|   import Ecto.Changeset | ||||
|   alias Ecto.{Changeset, UUID} | ||||
|   alias Memex.Accounts.User | ||||
|   alias Memex.{Accounts.User, Pipelines.Step} | ||||
|  | ||||
|   @primary_key {:id, :binary_id, autogenerate: true} | ||||
|   @foreign_key_type :binary_id | ||||
| @@ -18,6 +18,8 @@ defmodule Memex.Pipelines.Pipeline do | ||||
|  | ||||
|     belongs_to :user, User | ||||
|  | ||||
|     has_many :steps, Step, preload_order: [asc: :position] | ||||
|  | ||||
|     timestamps() | ||||
|   end | ||||
|  | ||||
|   | ||||
							
								
								
									
										65
									
								
								lib/memex/pipelines/step.ex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								lib/memex/pipelines/step.ex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| defmodule Memex.Pipelines.Step do | ||||
|   @moduledoc """ | ||||
|   Represents a step taken while executing a pipeline | ||||
|   """ | ||||
|   use Ecto.Schema | ||||
|   import Ecto.Changeset | ||||
|   alias Ecto.{Changeset, UUID} | ||||
|   alias Memex.{Accounts.User, Contexts.Context} | ||||
|   alias Memex.Pipelines.{Pipeline, StepContext} | ||||
|  | ||||
|   @primary_key {:id, :binary_id, autogenerate: true} | ||||
|   @foreign_key_type :binary_id | ||||
|   schema "steps" do | ||||
|     field :title, :string | ||||
|     field :content, :string | ||||
|     field :position, :integer | ||||
|  | ||||
|     belongs_to :pipeline, Pipeline | ||||
|     belongs_to :user, User | ||||
|  | ||||
|     many_to_many :contexts, Context, join_through: StepContext | ||||
|  | ||||
|     timestamps() | ||||
|   end | ||||
|  | ||||
|   @type t :: %__MODULE__{ | ||||
|           title: String.t(), | ||||
|           content: String.t(), | ||||
|           position: non_neg_integer(), | ||||
|           pipeline: Pipeline.t() | Ecto.Association.NotLoaded.t(), | ||||
|           pipeline_id: Pipeline.id(), | ||||
|           user: User.t() | Ecto.Association.NotLoaded.t(), | ||||
|           user_id: User.id(), | ||||
|           inserted_at: NaiveDateTime.t(), | ||||
|           updated_at: NaiveDateTime.t() | ||||
|         } | ||||
|   @type id :: UUID.t() | ||||
|   @type changeset :: Changeset.t(t()) | ||||
|  | ||||
|   @doc false | ||||
|   @spec create_changeset(attrs :: map(), position :: non_neg_integer(), Pipeline.t(), User.t()) :: | ||||
|           changeset() | ||||
|   def create_changeset(attrs, position, %Pipeline{id: pipeline_id, user_id: user_id}, %User{ | ||||
|         id: user_id | ||||
|       }) do | ||||
|     %__MODULE__{} | ||||
|     |> cast(attrs, [:title, :content]) | ||||
|     |> change(pipeline_id: pipeline_id, user_id: user_id, position: position) | ||||
|     |> validate_required([:title, :content, :user_id, :position]) | ||||
|   end | ||||
|  | ||||
|   @spec update_changeset(t(), attrs :: map(), position :: non_neg_integer(), User.t()) :: | ||||
|           changeset() | ||||
|   def update_changeset( | ||||
|         %{user_id: user_id} = step, | ||||
|         attrs, | ||||
|         position, | ||||
|         %User{id: user_id} | ||||
|       ) do | ||||
|     step | ||||
|     |> cast(attrs, [:title, :content]) | ||||
|     |> change(position: position) | ||||
|     |> validate_required([:title, :content, :user_id, :position]) | ||||
|   end | ||||
| end | ||||
							
								
								
									
										41
									
								
								lib/memex/pipelines/step_context.ex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								lib/memex/pipelines/step_context.ex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| defmodule Memex.Pipelines.StepContext do | ||||
|   @moduledoc """ | ||||
|   Represents a has-many relation between a step and related contexts | ||||
|   """ | ||||
|  | ||||
|   use Ecto.Schema | ||||
|   import Ecto.Changeset | ||||
|   alias Ecto.{Changeset, UUID} | ||||
|   alias Memex.{Contexts.Context, Pipelines.Step} | ||||
|  | ||||
|   @primary_key {:id, :binary_id, autogenerate: true} | ||||
|   @foreign_key_type :binary_id | ||||
|   schema "step_contexts" do | ||||
|     belongs_to :step, Step | ||||
|     belongs_to :context, Context | ||||
|  | ||||
|     timestamps() | ||||
|   end | ||||
|  | ||||
|   @type t :: %__MODULE__{ | ||||
|           step: Step.t() | Ecto.Association.NotLoaded.t(), | ||||
|           step_id: Step.id(), | ||||
|           context: Context.t() | Ecto.Association.NotLoaded.t(), | ||||
|           context_id: Context.id(), | ||||
|           inserted_at: NaiveDateTime.t(), | ||||
|           updated_at: NaiveDateTime.t() | ||||
|         } | ||||
|   @type id :: UUID.t() | ||||
|   @type changeset :: Changeset.t(t()) | ||||
|  | ||||
|   @doc false | ||||
|   @spec create_changeset(Step.t(), Context.t()) :: changeset() | ||||
|   def create_changeset( | ||||
|         %Step{id: step_id, user_id: user_id}, | ||||
|         %Context{id: context_id, user_id: user_id} | ||||
|       ) do | ||||
|     %__MODULE__{} | ||||
|     |> change(step_id: step_id, context_id: context_id) | ||||
|     |> validate_required([:step_id, :context_id]) | ||||
|   end | ||||
| end | ||||
							
								
								
									
										159
									
								
								lib/memex/pipelines/steps.ex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								lib/memex/pipelines/steps.ex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,159 @@ | ||||
| defmodule Memex.Pipelines.Steps do | ||||
|   @moduledoc """ | ||||
|   The context for steps within a pipeline | ||||
|   """ | ||||
|  | ||||
|   import Ecto.Query, warn: false | ||||
|   alias Memex.{Accounts.User, Repo} | ||||
|   alias Memex.Pipelines.{Pipeline, Step} | ||||
|  | ||||
|   @doc """ | ||||
|   Returns the list of steps. | ||||
|  | ||||
|   ## Examples | ||||
|  | ||||
|       iex> list_steps(%User{id: 123}) | ||||
|       [%Step{}, ...] | ||||
|  | ||||
|       iex> list_steps("my step", %User{id: 123}) | ||||
|       [%Step{title: "my step"}, ...] | ||||
|  | ||||
|   """ | ||||
|   @spec list_steps(Pipeline.t(), User.t()) :: [Step.t()] | ||||
|   def list_steps(%{id: pipeline_id}, %{id: user_id}) do | ||||
|     Repo.all( | ||||
|       from s in Step, | ||||
|         where: s.pipeline_id == ^pipeline_id, | ||||
|         where: s.user_id == ^user_id, | ||||
|         order_by: s.position | ||||
|     ) | ||||
|   end | ||||
|  | ||||
|   def list_steps(%{id: pipeline_id, visibility: visibility}, _invalid_user) | ||||
|       when visibility in [:unlisted, :public] do | ||||
|     Repo.all( | ||||
|       from s in Step, | ||||
|         where: s.pipeline_id == ^pipeline_id, | ||||
|         order_by: s.position | ||||
|     ) | ||||
|   end | ||||
|  | ||||
|   @doc """ | ||||
|   Preloads the `:steps` field on a Memex.Pipelines.Pipeline | ||||
|   """ | ||||
|   @spec preload_steps(Pipeline.t(), User.t()) :: Pipeline.t() | ||||
|   def preload_steps(pipeline, user) do | ||||
|     %{pipeline | steps: list_steps(pipeline, user)} | ||||
|   end | ||||
|  | ||||
|   @doc """ | ||||
|   Gets a single step. | ||||
|  | ||||
|   Raises `Ecto.NoResultsError` if the Step does not exist. | ||||
|  | ||||
|   ## Examples | ||||
|  | ||||
|       iex> get_step!(123, %User{id: 123}) | ||||
|       %Step{} | ||||
|  | ||||
|       iex> get_step!(456, %User{id: 123}) | ||||
|       ** (Ecto.NoResultsError) | ||||
|  | ||||
|   """ | ||||
|   @spec get_step!(Step.id(), User.t()) :: Step.t() | ||||
|   def get_step!(id, %{id: user_id}) do | ||||
|     Repo.one!(from n in Step, where: n.id == ^id, where: n.user_id == ^user_id) | ||||
|   end | ||||
|  | ||||
|   def get_step!(id, _invalid_user) do | ||||
|     Repo.one!( | ||||
|       from n in Step, | ||||
|         where: n.id == ^id, | ||||
|         where: n.visibility in [:public, :unlisted] | ||||
|     ) | ||||
|   end | ||||
|  | ||||
|   @doc """ | ||||
|   Creates a step. | ||||
|  | ||||
|   ## Examples | ||||
|  | ||||
|       iex> create_step(%{field: value}, %User{id: 123}) | ||||
|       {:ok, %Step{}} | ||||
|  | ||||
|       iex> create_step(%{field: bad_value}, %User{id: 123}) | ||||
|       {:error, %Ecto.Changeset{}} | ||||
|  | ||||
|   """ | ||||
|   @spec create_step(position :: non_neg_integer(), Pipeline.t(), User.t()) :: | ||||
|           {:ok, Step.t()} | {:error, Step.changeset()} | ||||
|   @spec create_step(attrs :: map(), position :: non_neg_integer(), Pipeline.t(), User.t()) :: | ||||
|           {:ok, Step.t()} | {:error, Step.changeset()} | ||||
|   def create_step(attrs \\ %{}, position, pipeline, user) do | ||||
|     Step.create_changeset(attrs, position, pipeline, user) |> Repo.insert() | ||||
|   end | ||||
|  | ||||
|   @doc """ | ||||
|   Updates a step. | ||||
|  | ||||
|   ## Examples | ||||
|  | ||||
|       iex> update_step(step, %{field: new_value}, %User{id: 123}) | ||||
|       {:ok, %Step{}} | ||||
|  | ||||
|       iex> update_step(step, %{field: bad_value}, %User{id: 123}) | ||||
|       {:error, %Ecto.Changeset{}} | ||||
|  | ||||
|   """ | ||||
|   @spec update_step(Step.t(), attrs :: map(), position :: non_neg_integer(), User.t()) :: | ||||
|           {:ok, Step.t()} | {:error, Step.changeset()} | ||||
|   def update_step(%Step{} = step, attrs, position, user) do | ||||
|     step | ||||
|     |> Step.update_changeset(attrs, position, user) | ||||
|     |> Repo.update() | ||||
|   end | ||||
|  | ||||
|   @doc """ | ||||
|   Deletes a step. | ||||
|  | ||||
|   ## Examples | ||||
|  | ||||
|       iex> delete_step(%Step{user_id: 123}, %User{id: 123}) | ||||
|       {:ok, %Step{}} | ||||
|  | ||||
|       iex> delete_step(%Step{}, %User{role: :admin}) | ||||
|       {:ok, %Step{}} | ||||
|  | ||||
|       iex> delete_step(%Step{}, %User{id: 123}) | ||||
|       {:error, %Ecto.Changeset{}} | ||||
|  | ||||
|   """ | ||||
|   @spec delete_step(Step.t(), User.t()) :: {:ok, Step.t()} | {:error, Step.changeset()} | ||||
|   def delete_step(%Step{user_id: user_id} = step, %{id: user_id}) do | ||||
|     step |> Repo.delete() | ||||
|   end | ||||
|  | ||||
|   def delete_step(%Step{} = step, %{role: :admin}) do | ||||
|     step |> Repo.delete() | ||||
|   end | ||||
|  | ||||
|   @doc """ | ||||
|   Returns an `%Ecto.Changeset{}` for tracking step changes. | ||||
|  | ||||
|   ## Examples | ||||
|  | ||||
|       iex> change_step(step, %User{id: 123}) | ||||
|       %Ecto.Changeset{data: %Step{}} | ||||
|  | ||||
|       iex> change_step(step, %{title: "new title"}, %User{id: 123}) | ||||
|       %Ecto.Changeset{data: %Step{}} | ||||
|  | ||||
|   """ | ||||
|   @spec change_step(Step.t(), position :: non_neg_integer(), Pipeline.t(), User.t()) :: | ||||
|           Step.changeset() | ||||
|   @spec change_step(Step.t(), attrs :: map(), position :: non_neg_integer(), User.t()) :: | ||||
|           Step.changeset() | ||||
|   def change_step(%Step{} = step, attrs \\ %{}, position, user) do | ||||
|     step |> Step.update_changeset(attrs, position, user) | ||||
|   end | ||||
| end | ||||
		Reference in New Issue
	
	Block a user