Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pikender/92e567ba8a3b685b02e77c6dd355fd17 to your computer and use it in GitHub Desktop.
Save pikender/92e567ba8a3b685b02e77c6dd355fd17 to your computer and use it in GitHub Desktop.
Add support for removing from schema as well
add support for removing from schema as well
diff --git a/apps/nectar/web/models/product.ex b/apps/nectar/web/models/product.ex
index 100e830..38174a7 100644
--- a/apps/nectar/web/models/product.ex
+++ b/apps/nectar/web/models/product.ex
@@ -2,7 +2,8 @@ defmodule Nectar.ModelExtension do
defmacro __using__(_opts) do
quote do
Module.register_attribute(__MODULE__, :schema_changes, accumulate: true)
- import Nectar.ModelExtension, only: [add_to_schema: 1]
+ Module.register_attribute(__MODULE__, :remove_schema_changes, accumulate: true)
+ import Nectar.ModelExtension, only: [add_to_schema: 1, remove_from_schema: 1]
@before_compile Nectar.ModelExtension
end
end
@@ -14,11 +15,39 @@ defmodule Nectar.ModelExtension do
end
end
+ defmacro remove_from_schema([do: block]) do
+ to_remove = Macro.escape(block)
+ quote bind_quoted: [to_remove: to_remove] do
+ Module.put_attribute(__MODULE__, :remove_schema_changes, to_remove)
+ end
+ end
+
+
defmacro __before_compile__(_env) do
quote do
- defmacro extensions do
- @schema_changes
+
+ defmacro extendable_schema(source, [do: orig_schema]) do
+ final_schema = __process_schema_changes__(orig_schema)
+ quote do
+ schema unquote(source) do
+ unquote(final_schema)
+ end
+ end
end
+
+ # rewrite the schema declaration
+ def __process_schema_changes__({:__block__, opts, declarations}) do
+ to_remove = @remove_schema_changes
+ to_add = @schema_changes
+ updated_declarations = Enum.filter(declarations, fn ({declaration_type, _declarataion_opt, declaration_params}) ->
+ # return false if found in to_remove list
+ !Enum.any?(to_remove, fn ({type, _opt, params}) ->
+ type == declaration_type && params == declaration_params
+ end)
+ end) ++ to_add # append the fields to add at the end of declaration list
+ {:__block__, opts, updated_declarations}
+ end
+
end
end
end
@@ -26,8 +55,11 @@ end
defmodule Nectar.ExtendProduct do
use Nectar.ModelExtension
- add_to_schema do: (field :special, :boolean, virtual: true)
- add_to_schema do: (field :type, :string, virtual: true)
+ add_to_schema do: (field :special, :boolean, virtual: true)
+ add_to_schema do: (field :type, :string, virtual: true)
+ remove_from_schema do: (field :slug, :string)
+ # must exactly match the declaration, no fuzzy matching supported
+ remove_from_schema do: (field :remove_me, :string, virtual: true)
end
defmodule Nectar.Product do
@@ -36,12 +68,15 @@ defmodule Nectar.Product do
use Nectar.Web, :model
use Arc.Ecto.Model
- schema "products" do
+ extendable_schema "products" do
field :name, :string
field :description, :string
field :available_on, Ecto.Date
field :discontinue_on, Ecto.Date
+
+ # let's remove these two
field :slug, :string
+ field :remove_me, :string, virtual: true
has_one :master, Nectar.Variant, on_delete: :nilify_all # As this and below association same, how to handle on_delete
has_many :variants, Nectar.Variant, on_delete: :nilify_all
@@ -52,7 +87,6 @@ defmodule Nectar.Product do
has_many :product_categories, Nectar.ProductCategory
has_many :categories, through: [:product_categories, :category]
- extensions
timestamps
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment