views:

127

answers:

3

Newbie here...I am just going through, what is clearly, an old rails tutorial.

To create a form they have the following code:

<%= start_form_tag(:action => 'create')%>

        <%= text_field(:album, :title) %><br />
        <%= text_field(:album, :artist) %><br />
        <%= text_field(:album, :genre) %><br />
        <%= datetime_select(:album, :release_date) %><br />

        <%= submit_tag("Create") %>

    <%= end_form_tag %> 

What is the proper Rails3 syntax for this code?

Thanks.

+1  A: 

I Would strongly suggest you to use two sites when it comes to RAILS Stuff !!!

  1. http://guides.rubyonrails.org/

  2. http://api.rubyonrails.org/

Good news is that... both the sites are updated with Rails 3 !!!

And yes as BBonifield specified you can use form_tag

KannanR
A: 

Why don't you try Micheal Hartl's Rails Tutorial , its probably one of the best guides for getting started with Rails, RailsCasts.com is pretty cool too.

Sid
I was going through that tutorial, but I couldn't get Rspec working on my system - so I went to another tutorial (a video tutorial that tends to be easier for me to follow along), but it is an early version of Rails and not Rails 3. So when I reach points like this form stuff, where the syntax and lots of stuff has changed, it makes it difficult to proceed.
marcamillion
+10  A: 

Quite a lot has changed since Rails 1 and I'm really impressed by the people who are willing to spend the time to sit down with Rails 3 and learn the differences (1). The community needs to be welcoming to these and the RTFM'ers aren't being helpful. This is where I think I can help out.

I would write that like this in Rails 3:

<%= form_for(@album) do |f| %>
  <p>
    <%= f.label :title %>
    <%= f.text_field :title %>
  </p>

  <p>
    <%= f.label :artist %>
    <%= f.text_field :artist %>
  </p>

  <p>
    <%= f.label :genre %>
    <%= f.text_field :genre %>
  </p>

  <p>
    <%= f.label :release_date %>
    <%= f.datetime_select :release_date %>
  </p>

  <%= f.submit %>
<% end %>

Woah, so many changes! Where do we begin? The top line, of course!

form_for is a method that's been in Rails for a while and has become exceedingly useful over the past couple of major revisions. This method will take the @album variable set up in the controller and inspect it to determine a couple of things 1) where the form should go 2) what the values of the fields should be.

I should mention at this stage that it should be mentioned that your app/views/albums/new.html.erb should now look like this:

<h2>New Album</h2>
<%= render "form" %>

OMG, more new stuff! It's ok: render "form" will render the app/views/albums/_form.html.erb partial. This is where the above form_for tomfoolery should live now. Why? Let me continue explaining.

In your AlbumsController's new action, you'd have something like this:

def new
  @album = Album.new
end

form_for is smart enough to go: "hey, that's a new Album resource, he probably wants to go to the create action for this form because he's being a good lad and following the Rails conventions", so that's precisely what it'll do.

Except:

This will raise an exception that there's no albums_path method defined. What the?

In Ruby on Rails 2, RESTful routing became a Big Thing. It's best if you read the routing guide, since if I explained it I would only be repeating a lot of it. Basically: RESTful routing is a convention for the URL routes of your application that determines that when we do a POST (it's a form, remember?) to /albums, this will go to the create action.

But how does Rails know to do this?

Because in your config/routes.rb file you've put this line:

resources :albums

This defines routes to "The Seven" default actions of your controller (index, show, new, create, edit, update and destroy). Seriously, read the routing guide to know all about this beauty.

So back to our little form_for. It knows to go to /albums for a new object, which is cool and all. So what's up with the f block argument? Well, this is a form builder object which allows us to build form elements for the specific Album object from our new (and soon, edit) actions. When we call:

<%= f.text_field :title %>

We are doing the Rails 1 equivalent of:

<%= text_field :album, :title %>

It's just a little bit of syntatic sugar that Rails gives you in order to make your views more DRY.

I also added labels to your form because users need to know what the fields are that they're filling in. The beautiful part here is that the user won't see :title, but will see Title instead. For :release_date, they'll see "Release Date". Beautiful.

At the end of the form, I use f.submit. This will generate a submit button that says either "Create Album" if @album is a new object, or "Update Album" if it's a pre-existing object. But where do the pre-existing objects get edited?

In the edit action!

def edit
  @album = Album.find(params[:id]
end

In your app/views/albums/edit.html.erb file you'd have much the same you have in its new.html.erb sibling:

<h2>Editing Album</h2>
<%= render "form" %>

You can use precisely the same line in both of these to render the same partial, but it will perform differently if the object is new or if it is pre-existing (commonly referred to as persisted).

In the case of the edit action rendering this partial, it will generate a route to /albums/1 for the form and do a Rails-specialty PUT request to this resource. Another thing the routing guide will explain very well, I hope.

I'm sorry for the length of this answer but there's no real short answer for this question, it's quite a large change but trust me when I say it really is for the better.

Rails 3 rocks.

(1) Less so with the people who aren't.

Ryan Bigg
OMG dude.....i can't thank you enough for this answer. That looks NOTHING like the dozen permutations I have been trying. I haven't even tried it, and therefore can't verify that it works - just yet - but I have to THANK YOU for this. It is people like you, why I love stack overflow. Honestly, the other answers really discouraged me, but you have come through in a big way. I wish I could upvote this 20 times and mark it answered 200 times :) Thanks again.
marcamillion
Btw, this is prolly a REALLLY dumb question, but in Rails 3, do they no longer use .rhtml views? I keep seeing you reference '.html.erb'. I am still going through the tutorial, so maybe they will get to that in a few, but I noticed that in the `/app/views/layouts` folder I do have an '.html.erb' file, but I haven't had to interact with that much yet.
marcamillion
Btw...just followed all your instructions and it worked perfectly. Thanks again man. Really appreciate it.
marcamillion
@marcamillion: No worries, glad to help out! Ah yes, the `.rhtml` extension is something that I totally had forgotten about! In Rails 3 there's now the `.html.erb` extension for these files where the file name is `<format>.<extension>`, which is how Rails can decide what template to render based on the request type. The "Getting Started" guide kinda covers this with mention to respond_to, but nothing seriously in-depth.
Ryan Bigg
Also: there's no such thing as a dumb question. Knowledge should be shared, never hoarded.
Ryan Bigg