Using form_tag in Ruby on Rails

I had some trouble finding a less than simplistic example of using the form_tag in Rails yesterday and, after griping on twitter about it was called out and told to do it myself.  Good advice.  Here we go.

In Rails you’ve got two ways to create a form:  form_for and form_tag.  You see examples for form_for everywhere, because that’s what you use to directly interact with the models you created in your database.  But a lot of times you need to create a form that has no interaction with your database and that isn’t mapped to any data model.  Enter form_tag.

There are two syntatic differences between forms created with form_for and those with form_tag.  First, you typically declare form_for like this:

<% form_for(@person) do |f| %>

And from then on you add fields using the f variable you just defined, like f.text_field or f.select.  The other difference is that the way you declare the fields themselves changes.  text_field becomes text_field_tag, select becomes select_tag and so on.  The reason is that text_field is meant, just like form_for, to interact with a defined object model.  All those ones ending in _tag are for unbound forms.

<% form_tag(create_ticket_path, :method=>'post', :multipart => true) do %>

In the example, you see a couple of things.  First, when defining a form_tag you can’t just pass it an object and let rails figure out what needs to happen.  You need to tell it, first, what URL to point at and, second, what HTTP call to make (typically post or put).  Those are the first two parameters. In my case, I have a path defined in my routes.rb for create_ticket, so I can call create_ticket_path to get it. And I’m creating a support ticket, so I’m going to use the ‘post’ method.

The third parameter is where you pass your options, which are roughly the same as the options you can pass form_for.  You’ll see in mine I passed it :multipart => true.  I do that to define a multipart form so that I can let people upload a file on submission.

The other thing to note is when defining the input fields.  When using form_for, you can just pass, say, text_field the symbol for the field you want it bound to. So, if you were creating a field for the subject of a support ticket request, you’d do:

<%= f.text_field :subject %>

Rails figures out the rest.  Without the model, we need to do it ourselves and define the field’s id.  (If you wanted to have a default value, you’d put it in the second parameter, but for this example it doesn’t really make sense).

<%= text_field_tag "subject" %>

Pretty simple, I know.  But sometimes you just need to see how the syntax works, and it felt like every tutorial assumed every form would either use Rails’ models and form_for, or your form_tag usage would be hilariously simple.  The full example of the form is below.  Just like when you use form_for, if you’re catching this with a rails controller, everything will be available through the params[] array.  So, to catch that text_field_tag “subject” all you have to do in your controller is grab for params[:subject] .

File uploads are their own story, but to get you started, it’ll be in params just like everything else. Just be sure to use :multipart => true or your form will quietly ignore that an attachment was chosen.

Easy, right?

<% form_tag(create_ticket_path, :method=>'post', :multipart => true) do %>
 <p>
   Subject:<br />
   <%= text_field_tag "subject" %>
 </p>
 <p>
   Priority: <br />
   <%= select_tag("priority", options_for_select([['Critical', '1'],
                 ['Important', '2'],['Standard','3']], '3')) %>
 </p>
 <p>
   Describe your problem:<br />
   <%= text_area_tag "description", "", :size=>"50x20" %>
 </p>
 <p>
   Add an attachment:<br />
   <%= file_field_tag "attachment" %>
 </p>
 <p>
   <%= submit_tag 'Submit' %>
 </p>
<% end %>
This entry was posted in Coding. Bookmark the permalink.

35 Responses to Using form_tag in Ruby on Rails

  1. my_elf says:

    Great article :)

  2. gullom says:

    Simple and effective article…Was looking for similar info and basic example of form_tag so thanks!

  3. Horace Ho says:

    How can I group params in form_tag?

    For example, what if I want the params[:subject] and params[:description] to be grouped into

    params[:ticket][:subject], and
    params[:ticket][:description] ?

    such that the form_tag variables are not ‘mixed’ with other params (e.g. params[:action], params[:controller]. …, etc.)

    thx, and great article!

  4. BSise says:

    This really helped me in in designing a submission form for my language learning site iLearnWords (http://www.ilearnwords.com) — thank you!

    BSise

  5. Hal Helms says:

    Thanks very much! Great, focused tutorial.

  6. Navin says:

    Good work – helped this newbie! Have you considered doing an article on fields_for as well?

  7. Asif Sheikh says:

    This article was very helpful. Thank you :)

  8. Hi,

    Nice article, just what I needed, sometimes the Rails API docs really are sparse.

    A note for new users like me, the code to do something with the data you get form the user goes in the same controller method as the one that called the page in the first place, typically this is your index method.

    Richard.
    IT Contractor Mortgages

  9. arivarasan says:

    nice work! It will help the newbie(me too) for rails…

  10. Artem says:

    very good and clear information

  11. RORails says:

    Thanks a ton for this.

  12. Spyros says:

    I’m having some trouble on getting that to work. I want to pass a work_hours param. My route is :

    post ‘start/:work_hours’ => :start, :as => ‘start’

    My code is :

    :post do %>

    But i get a “No route matches {:controller=>”labor”, :action=>”start”}” when rendering the form. Any idea on what i’m doing wrong ? :/

  13. saalon says:

    Spyros,

    Is the comment system cutting off part of your code? What you posted looks a little incomplete. I don’t think WordPress does a great job handling code in comments.

    I suggest posting your question on http://stackoverflow.com and, if you’d like, leaving the link to the question here. I’d be happy to answer it (and if I can’t, someone else there probably can).

    Eric

  14. bhavesh says:

    fine explanation

  15. supriya says:

    thanks a lot.. great work

  16. Dave says:

    Awesome article, just what I needed when I was about ready to throw my laptop out the window because form_tag was breaking my code. Thanks!

  17. Pingback: Whoever You Were: Love | Saalon Muyo

  18. Ed Castano says:

    Very helpful, thanks! The Rails documentation doesn’t really lend a hand here.

  19. Charlie says:

    Thank you so much! I was trying to find “official” docs on this and nothing layed it out as clear and concise.

  20. chetanM says:

    Gr8 To newb !!!

  21. Anand Hegde says:

    thanks a lot – trippin.in

  22. qqq says:

    You are missing a “=” in the form_tag. Good tutorial though

  23. Juan Carrillo says:

    Thank you. I am learning Ruby on Rails and I must change a form_for with form_tag and with your tutorial I will do it.

  24. Assaf Shomer says:

    Thanks!

  25. Chandan says:

    Thanks a lot :)

  26. Matias L. says:

    Thanks man! You save me, now I’m not going to get crazy haha. You have been very clear with the explanation. Again, thanks a lot!

  27. Nikitha says:

    Great tips in here! I found the create_ticket_path especially helpful, because I was really struggling with how to link it up to a controller!

  28. gorn says:

    @Horace Ho

    just use

    text_field_tag “ticket[subject]”
    text_area_tag ‘ticket[description]’

  29. Deyler Santos Paiva says:

    Very nice. It helped me a lot! Thank you!

  30. Shuki says:

    You need an ‘=’ before ‘form_tag’

  31. john says:

    @gron

    That was incredibly helpful, thank you.

  32. Nate says:

    Thank you for clarifying the difference between form_for and form_tag.

    Nate
    Pro Lighting Rental

  33. Haris says:

    Thanks for the great insight. I am currently learning rails and was wondering when to use form_tag and form_for, and this help me get a clear understanding.

  34. I have been looking everywhere for this info. Thank you so much for posting.

  35. Sofia says:

    Very helpful and straightforward article, exactly what I was looking for! Thank you!

Leave a Reply

Your email address will not be published. Required fields are marked *