DEV Community

Cover image for Getting wet with phoenix
Mohammed sadique palakkal
Mohammed sadique palakkal

Posted on

Getting wet with phoenix

Now a days writing phoenix CRUD application is not a hurdle for beginners. After completing installation with in few steps your initial project is up and running. and we have some magic codes to create new HTML resources with views,controllers and contexts. now we are not going to that part right now, before using those magic codes in your project having a clear picture about context, controllers and views will give a happy path in your coding life. so let us jump to a all those things by a sample phoenix project.

The parts of a html resource in phoenix project is as follows

  • Migration
  • Schema
  • Changeset
  • Context
  • Controller
  • View
  • Template
  • Router

Let's do a project by covering all these steps

Create a phoenix project

mix phx.new greeting_cards
We are almost there! The following steps are missing:

    $ cd greeting_card

Then configure your database in config/dev.exs and run:

    $ mix ecto.create

Start your Phoenix app with:

    $ mix phx.server

You can also run your app inside IEx (Interactive Elixir) as:

    $ iex -S mix phx.server

Enter fullscreen mode Exit fullscreen mode

Hope you done all step by step, in case of any errors check installation guide

Let's start with a feature

We created a project named greeting_cards my let us assume its an app for greeting card design collections as an initial step we should feed collection of greeting cards in our database.

Migration

mix ecto.gen.migration create_greeting_cards

==> greeting_card
Compiling 14 files (.ex)
Generated greeting_card app
* creating priv/repo/migrations/20220903182959_create_greeting_cards.exs

Enter fullscreen mode Exit fullscreen mode

Navigate to .exs generated shown in output
Update the file with these scripts to

defmodule GreetingCard.Repo.Migrations.CreateGreetingCards do
  use Ecto.Migration

  def change do
    create table(:greeting_cards) do
      add :name, :string
      add :type, :string
      add :template, :string
      add :print_quality, :string
      add :preview, :string
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

And run mix ecto.migrate

Will create table "greeting_cards" in your database

Context

An encapsulation layer for data access and validation, so the schemas are grouped under a context name for more details
refer Contexts

Create

lib/greeting_cards/feeder.ex
lib/greeting_cards/feeder/         #Directory
Enter fullscreen mode Exit fullscreen mode

Schema

An Ecto.Schema maps External data into elixir structs, a Schema file contains specification of fields for database table and Changesets to allow filtering, casting, validation and definition of constraints when manipulating structs.
Schema
Chngeset
Here to create our schema for greeting cards
Create

lib/greeting_cards/feeder/greeting_card.ex


defmodule GreetingCard.Feeder.GreetingCard do
  use Ecto.Schema
  import Ecto.Changeset

  schema "greeting_cards" do
    field :name, :string
    field :type, :string
    field :template, :string
    field :print_quality, :string
    field :preview, :string
  end

 def changeset(greeting_card, params \\ %{}) do
    greeting_card
    |> cast(params, [:name, :type, :template, :print_quality, :preview])
    |> validate_required([:name, :type, :print_quality])
  end

Enter fullscreen mode Exit fullscreen mode

Write Context functions

We mapped our database table with an Elixir struct by a Schema module then we can write functions to do CRUD operations
To write CRUD functions Refer
Ecto.Repo

Update lib/greeting_cards/feeder.ex

defmodule GreetingCard.Feeder do
  alias GreetingCard.Repo
  alias GreetingCard.Feeder.GreetingCard

  def list_greeting_cards do
    Repo.all(GreetingCard)
  end

  def create_greeting_card(params) do
    %GreetingCard{}
    |> GreetingCard.changeset(params)
    |> Repo.insert()
  end

  def show_greeting_card(id) when not is_nil(id) do
    Repo.get(GreetingCard, id)
  end

  def update_greeting_card(greeting_card, params) do
    greeting_card
    |> GreetingCard.changeset(params)
    |> Repo.update()
  end

  def delete_greeting_card(greeting_card) do
    Repo.delete(greeting_card)
  end
end

Enter fullscreen mode Exit fullscreen mode

Run and test our code using iex shell

So far we are writing codes to create a feature, debugging and running is an another interested part of coding, before running our feature in to a web server let's run that in our iex shell and make sure all our functions are working as we expected
In terminal project root directory run
iex -S mix
Call your functions in shell through module name here

iex(2)> GreetingCard.Feeder.create_greeting_card(%{name: "card1",type: "birthday", template: "template1",print_quality: "canva"})
[debug] QUERY OK db=1.4ms queue=2.0ms idle=1173.7ms
INSERT INTO "greeting_cards" ("name","print_quality","template","type") VALUES ($1,$2,$3,$4) RETURNING "id" ["card1", "canva", "template1", "birthday"]
 :erl_eval.do_apply/6, at: erl_eval.erl:685
{:ok,
 %GreetingCard.Feeder.GreetingCard{
   __meta__: #Ecto.Schema.Metadata<:loaded, "greeting_cards">,
   id: 1,
   name: "card1",
   preview: nil,
   print_quality: "canva",
   template: "template1",
   type: "birthday"
 }}
iex(3)> GreetingCard.Feeder.list_greeting_cards                                                                 [debug] QUERY OK source="greeting_cards" db=0.9ms idle=1687.7ms
SELECT g0."id", g0."name", g0."type", g0."template", g0."print_quality", g0."preview" FROM "greeting_cards" AS g0 []
 :erl_eval.do_apply/6, at: erl_eval.erl:685
[
  %GreetingCard.Feeder.GreetingCard{
    __meta__: #Ecto.Schema.Metadata<:loaded, "greeting_cards">,
    id: 1,
    name: "card1",
    preview: nil,
    print_quality: "canva",
    template: "template1",
    type: "birthday"
  }
]
iex(4)> GreetingCard.Feeder.show_greeting_card(1)
[debug] QUERY OK source="greeting_cards" db=0.5ms queue=0.6ms idle=373.3ms
SELECT g0."id", g0."name", g0."type", g0."template", g0."print_quality", g0."preview" FROM "greeting_cards" AS g0 WHERE (g0."id" = $1) [1]
 :erl_eval.do_apply/6, at: erl_eval.erl:685
%GreetingCard.Feeder.GreetingCard{
  __meta__: #Ecto.Schema.Metadata<:loaded, "greeting_cards">,
  id: 1,
  name: "card1",
  preview: nil,
  print_quality: "canva",
  template: "template1",
  type: "birthday"
}
Enter fullscreen mode Exit fullscreen mode

Run with server

So far we are working on the data layer of our feature, we have to implement view and controller layers as well. Phoenix project contains a Routing Module by default to specify routers. They are the main hubs of phoenix application, They match HTTP requests to controller actions,wire up real-time channel handlers, etc..

Refer Request Life cycle

Top comments (0)