Den första gången jag introducerades till Ruby on Rails blev jag ganska överväldigad. Det var det första programmeringsramverket jag lärde mig och jag måste säga att jag blev lite förälskad. Jag hade precis lärt mig att bygga program med Sinatra och tyckte att det var ett ganska häftigt verktyg, men sedan såg jag vad Rails kunde göra…

En huvudfunktion i Rails som jag verkligen gillade att använda var From Helpers. Det gjorde att jag kunde undvika att skriva ut all HTML för att bygga ett formulär, vilket i sin tur gav mig möjlighet att göra mer komplexa funktioner. I den här artikeln kommer jag att bryta ner de olika formulärhjälparna som finns i Rails och även beröra en ny som lanserades i Rails 5.1-releasen.

Skapa formulär med HTML kan ibland vara besvärligt, särskilt när de är extra långa med alldeles för många inmatningsfält. De kan bli ännu knepigare när du behöver att formuläret ska skicka data till en specifik api-slutpunkt eller associeras med en databasmodell. Här är ett html-formulär för att skapa en användare:

<form class="new_user" action="/users" method="post">
<label for="user_name">Name</label>
<input type="text" name="user">
<br>
<label for="user_password">Password</label>
<input type="password" name="user">
<br>
<input type="submit" name="commit" value="Create User" data-disable-with="Create User">
</form>

Som du ser kan det bli komplicerat att skriva allt detta ganska snabbt. Om du tittar närmare på formuläret kan du se att vi skickar ett action- och metodattribut till vårt formulär för att skapa en ny användare. Detta är bra och allt, men Rails är superpetig när det gäller att skicka in formulär. Just det här formuläret skulle inte klara sig när det skickades in. Det är här som Form helpers kommer till undsättning.

Form Helpers

När jag först lärde mig att använda Form helpers kunde jag ärligt talat inte tro vad de gjorde. Som du såg från det tidigare formuläret som vi gjorde tar det en del tid och komplexitet att åstadkomma. Men med form helpers kan detta uppnås med mycket mindre arbete och med en hel del ”magi”.

Det finns tre olika helpers som hjälper oss att bygga snabba och användbara formulär i Rails, form_tag, form_for och form_with. Den sista, form_with, introducerades i samband med lanseringen av Rails 5.1 och kombinerar i huvudsak de två förstnämnda hjälparna.

form_tag

Den form_tag är den mest grundläggande av hjälparna och gör i sin tur mindre ”magi” åt dig. Den bygger fortfarande upp formuläret åt dig, men du måste vara mer explicit när du deklarerar url-sökvägar och den används främst när formuläret inte är kopplat till en Controller#action. Låt oss använda ett grundläggande sökformulär som exempel:

<%= form_tag("/search", method: "get") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
<% end %>

Detta kommer att generera följande HTML:

<form accept-charset="UTF-8" action="/search" method="get">
<input name="utf8" type="hidden" value="&#x2713;" />
<label for="q">Search for:</label>
<input name="q" type="text" />
<input name="commit" type="submit" value="Search" />
</form>

Som du kan se deklarerar vi rutten vi vill att formulärparametrarna ska skickas i form_tag. Du kan se att detta sker i raden <%= form_tag("/search", method: "get") do %> och du kan också se att vi specificerar http-förfrågan. Detta är fortfarande ganska häftigt och du kan se att Rails tar hand om mycket åt oss även i den grundläggande formulärhjälpen, men Rails har en mer kraftfull version av detta…

form_for

Form_for är den riktiga varan. Med den här hjälpen kan vi binda ett formulär till ett objekt, vilket gör att vi kan skapa/redigera ett objekt. Som vi såg i form_tag-exemplet var vi tvungna att vara explicita i vilken url-sökväg vi skulle använda för att skicka in formulärparametrarna, men form_for låter oss abstrahera detta. Här är ett exempel:

<%= form_for @user do |f| %> <%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit %><% end %>

Detta ger samma kod som vi såg i vårt första exempel på ett html-formulär.

<form class="new_user" action="/users" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓">
<input type="hidden" name="authenticity_token"
value="QPJXa5iS/XNvodHhpcwV5q42RoGFWsmZkwL3ATHFfeKqxZ8IQsLs1QjJvcrdO3BwCaOfQ4TxNLDD0b6VbxiACg=="> <label for="user_name">Name</label>
<input type="text" name="user">
<br>
<label for="user_password">Password</label>
<input type="password" name="user">
<br>
<input type="submit" name="commit" value="Create User" data-disable-with="Create User"></form>

Du ser direkt hur mycket renare den här koden ser ut med form_for. Ärligt talat är det lite häpnadsväckande att en så liten kod kan skapa all denna html, men det gör den verkligen! Du kan se i den första raden i form_for att vi lämnar över en instansvariabel för användaren vilket kommer att knyta detta formulär till det objektet. Den andra häftiga saken med att lämna in denna variabel är att Rails kommer att leta efter lämplig url-sökväg på sin egen, jämfört med form_tag där vi var tvungna att uttryckligen tala om för den var den ska skicka data.

form_with

  • Kanske tala om form_with och om dess användning
  • Använda kodutdrag till exempel

Om du tittar på Ruby on Rails 5.1 Release Notes finns det en anteckning om att form_for och form_tag förenas till form_with. Den största fördelen med denna nya hjälpreda är form_with kan generera formulärtaggar baserat på URL:er, scopes eller modeller

Vi testar det!

form_with using URLs

Låt oss använda samma exempel som vi använde i form_for och tillämpa det med form_with med bara en URL:

<%= form_with url: user_path do |f| %>
<%= f.label :first_name %>
<%= f.text_field :first_name %>
<%= f.label :last_name %>
<%= f.text_field :last_name %>
<%= f.submit %>
<% end %>

Som du kan se är det väldigt likt form_tag där vi anger en specifik URL (user_path)

form_with using models

Den riktigt häftiga grejen med form_with är att det också kan användas för att skicka in modellobjekt, i likhet med form_for.

<%= form_with model: @user do |f| %>
<%= f.label :first_name %>
<%= f.text_field :first_name %>
<%= f.label :last_name %>
<%= f.text_field :last_name %>
<%= f.submit %>
<% end %>

Detta kommer att skapa samma HTML som producerades genom att använda form_for.

Vår största fördel med form_with är att vi inte längre behöver oroa oss för att bestämma oss mellan form_tag och form_for. Vi har en smart hjälpreda som gör att vi kan göra båda jobben med bara ett byte i den första raden i det deklarerade formuläret.

Slutsats

Rails formulärhjälpare är grymma och det nya tillägget form_with samlar verkligen alla fördelarna med både form_tag och form_for. Du har nu ett verktyg som gör att du kan bygga ett formulär baserat på vad du än behöver. Vare sig det är ett sökformulär eller ett formulär för att överföra data till din databas, kan du ta hand om det med Rails form helpers.

Jag skulle också föreslå att du går igenom Rails Guides för att lära dig hur du gör mer komplexa formulär. Du har en hel del alternativ från att låta en modell acceptera nästlade attribut, ha nästlade attribut och andra formulärhjälpare för att skapa anpassade inmatningsfält. Det finns så mycket att leka med när man går igenom dessa dokument så dra nytta av det!

Happy Coding!

Lämna ett svar

Din e-postadress kommer inte publiceras.