In my application to search for rooms I have added some features in room. Like availity of parking space, Internet, pets friendly, kids friendly and some more. When adding the rooms for rent user will have check the check box to indicate the availability of the features. This features will further mapped to the many to many relation in our database.
Node: I have added common pitfalls and their solution at the last.
mix phx.gen.context Amenities Amenity amenities name
Before migrating let’s add unique constraint in the migration file
mix ecto.migrate
I already Had a Rooms Context and its schema (schema shown below), Next I generated juction table called…
Make a field nullable
mix ecto.gen.migration add_nullable_to_fiel
d
def change do
alter table(:events) do
modify(:title, :string, null: true, from: :string) # Title column is now nullable
end
end
Add field to existing table
mix ecto.gen.migration add_is_super_admin_to_merchant
Add references to existing table
mix ecto.gen.migration add_district_id_to_room
defmodule Tailwind.Repo.Migrations.AddedDistrictIdToRoom do use Ecto.Migration
def change do
alter table :rooms do
add :district_id, references( :districts, on_delete: :delete_all)
end
end
end
Add Unique index to a field
I forgot to add unique constraint in email. so generating a migration to add constraint in email.
mix ecto.gen.migration add_uniq_constraint_to_email_on_merchant
Then do mix ecto.migrate
if you got error like “Key (email)=(abc@abc.com) is duplicated.”, that means you already have multiple values in database of same email. Remove those duplicate values and run the migrate command again.
We also need to add unique constraint for email in model .
While in mobile application we needed to install sdk for google maps, I found it somewhat similar in the web too. Easy part is that we can add it via cdn. And hard part is that we have to use Javascript. :) But It was not that hard though.
<div class="w-1/4 h-70">
<div id="googleMap" style="width:100%;height:400px;"></div></div>
I created div
with id equal to googleMap
Then in script below just added this.
<script> function myMap() { var mapProp = { center: new google.maps.LatLng(51.508742, -0.120850), zoom: 5, }; var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);}
</script><script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY&callback=myMap"></script>
We need key for googlmaps to work otherwise we can pass empty to start in development…
Small elixir snippets that actually works, now thats called fun.
Automating tedious jobs are sure fun. I am writting an Roomfinder application as a part of my through learning elixir, phoenix and web development as a whole.
I am from Nepal. Nepal has 77 district and 7 States. I needed to create a database table from it.
I added above json file in priv/static/json/district_list.json
Then generated context using
mix phx.gen.context Districts District districts name state:integer
mix ecto.migrate
Then in seeds.exs file I added a script to read the file and loop through all and insert it to database.
And thats it without any error all address are now inside my postgres database.
Phoenix Auth Has never been so simple
I already written how to add social authentication in phoenix
But for email password authenitcation Its amazingly simple now.
open mix.exs and add deps.
{:phx_gen_auth, “~> 0.6.0”}
Then run,
mix phx.gen.auth Accounts User users
mix ecto.migrate
and thats it. We have full fledge authentication system.
run the server and try it in the browser
http://localhost:4000/users/log_in
you should see login page.
Bonus:
To guard a routes we can pass scope through the require_authenticated_user
plug. It is already in our route file generate by phx_gen_auth
pipe_through [:browser, :require_authenticated_user]
To guard a specific action in controller
import TailwindWeb.UserAuth, only: [require_authenticated_user: 2]plug :require_authenticated_user when action in [:my_rooms, :new, :edit, :delete]
Authentication is always hard for someone new in the field. But once we do it, Oh.. It feels good.
I had experience with social authentication in mobile application. So I had some faint concept, But this is my first time doing social authentication with web. I did got into unexpected handshake errors
which was really hard to debug. Will tell about this at the end. First let’s get started.
First let’sueberauth_facebook
and ueberauth_google
as dependency
def deps do
[{:ueberauth_facebook, "~> 0.8"}], {:ueberauth_google, "~> 0.10"},end
mix deps.get
Then configured ueberauth
for facebook strategy in config.exs
. …
Since I am learning Elixir and phoenix, I thought tinker with my web app I already had up with Nodejs. I used Sequelize with nodejs and my table had column names as camelCase. But Ecto, by default follows the snake_case convention. But Integrating was quite easy and painless.
I generated Account models with mix
phx.gen.html Accounts User users email f_id g_id
deleted the migration file generated.
And updated the schema as follows:
schema "users" do field :email, :string field :fb_id, :string field :g_id, :string field :name, :string field :inserted_at, :utc_datetime, source: :createdAt field :updated_at, :utc_datetime, source: :updatedAt# timestamps()end
I had problem with timestamps. …
Adding Jquery may seems like trival but for someone not from web platform, I really did Felt the fatigue, hunting solution for hours and hours. It was like walking an unknown territory in complete dark, sometimes there were faint light shown by stackoverflow, github and google. But there were also pitch dark times when I, alone, went deep inside the forest of my inexperiences. But finally, once I got that final missing link, It turned out to be quite simple. And ultimately became trivial for me too.
cd assets
and do yarn add jquery
open webpack.config.js
and add the following.
const webpack =…
inside assets
folder
yarn add @fortawesome/fontawesome-free
yarn add file-loader
in assets/css/ create a file called _variables.scss
add the following line.
$fa-font-path: "~@fortawesome/fontawesome-free/webfonts";
import following in app.scss
file.
@import "variables";@import "@fortawesome/fontawesome-free/scss/brands";@import "@fortawesome/fontawesome-free/scss/regular";@import "@fortawesome/fontawesome-free/scss/solid";@import "@fortawesome/fontawesome-free/scss/fontawesome";
If you dont have sass-loader inside rules, in webpack.config.js
, add it now
{ test: /\.[s]?css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader', 'postcss-loader' ],}
Also while in webpack.config.js, lets configure the file-loader to load fontawesome
{ test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/, use: [ { loader: 'file-loader', options: { name: '[name].[ext]', outputPath: '../fonts' } } ]},
Add fontawesome icon in app.html.eex. and test it
<i class=”fas fa-bars”></i>
we should see this icon
We will also add tailwind forms and tailwind-aspect-ratio for working with images.
mix phx.new tailwind
cd assets
yarn add --dev autoprefixer postcss postcss-loader postcss-import tailwindcss
create a file postcss.config.js
inside assets directory
// postcss.config.js
module.exports = {
plugins: [
require('tailwindcss'),
require('autoprefixer')
]
}
open webpack.config.js
and change sass-loader
to postcss-loader
{ test: /\.[s]?css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader', 'postcss-loader' ],}
open app.scss
and delete all content. and add
@import "tailwindcss/base";@import "tailwindcss/components";@import "tailwindcss/utilities";
inside assets directory, run (optional)
npx tailwind init --full // --full is optional too
this will generate a tailwind.config.js
file which you can use to extend the tailwindcss if necessary (we will use it to add a form…
About