Drops.Relation.Plugins.Views (drops_relation v0.1.0)
View SourcePlugin for defining relation views with custom schemas and derived queries.
Views allow you to create specialized versions of a relation with:
- Custom field selection (subset of original fields)
- Derived query operations (automatic filtering/restrictions)
- Separate struct modules for type safety
Usage
defmodule MyApp.Users do
use Drops.Relation, repo: MyApp.Repo
schema("users", infer: true)
view(:active) do
schema([:id, :name, :email]) # Only include specific fields
derive do
restrict(active: true) # Automatically filter active users
end
end
end
# Use the view
active_users = MyApp.Users.active().all() # Returns only active users with limited fields
Examples
Basic View with Field Selection
iex> defmodule BlogApp.Users do
...> use Drops.Relation, repo: MyApp.Repo
...> schema("users", infer: true)
...>
...> view(:active) do
...> schema([:id, :name, :active])
...>
...> derive do
...> restrict(active: true)
...> end
...> end
...> end
iex>
iex> # View returns only active users with limited fields
iex> active_users = BlogApp.Users.active().all()
iex> length(active_users)
2
iex> hd(active_users).name
"John Doe"
...>
iex> hd(active_users).active
true
...>
iex> Map.has_key?(hd(active_users), :email)
false
View with Custom Struct Name
iex> defmodule BlogApp.Posts do
...> use Drops.Relation, repo: MyApp.Repo
...>
...> schema("posts", infer: true)
...>
...> view(:published) do
...> schema([:id, :title, :view_count, :published], struct: "PublishedPost")
...>
...> derive do
...> restrict(published: true)
...> |> order(desc: :view_count)
...> end
...> end
...> end
iex>
iex> # View returns published posts ordered by view count
iex> published_posts = BlogApp.Posts.published().all()
iex> length(published_posts)
3
iex> hd(published_posts).__struct__
BlogApp.Posts.Published.PublishedPost
iex> hd(published_posts).title
"First Post"
iex> hd(published_posts).view_count
100
Multiple Views on Same Relation
iex> defmodule BlogApp.Analytics do
...> use Drops.Relation, repo: MyApp.Repo
...>
...> schema("posts", infer: true)
...>
...> view(:popular) do
...> schema([:id, :title, :view_count, :published])
...>
...> derive do
...> restrict(published: true)
...> |> order(desc: :view_count)
...> end
...> end
...>
...> view(:recent_drafts) do
...> schema([:id, :title, :user_id, :published])
...>
...> derive do
...> restrict(published: false)
...> end
...> end
...> end
iex>
iex> # Popular posts view
iex> popular = BlogApp.Analytics.popular().all()
iex> length(popular)
3
iex> hd(popular).title
"First Post"
iex> hd(popular).view_count
100
iex> drafts = BlogApp.Analytics.recent_drafts().all()
iex> length(drafts)
1
iex> hd(drafts).title
"Draft Post"