views:

403

answers:

2
  <% form_tag(:action=>'update', :id=>@album.id) do %>

  Title: <%= text_field(:album, :title)  %><br>
  Artist: <%= text_field(:album, :artist)  %><br>
  Genre: <%= text_field(:album, :genre)  %><br>
  Release Date: <%= datetime_select(:album, :release_date, :start_year=>1960) %><br>

  <%= submit_tag("Update") %>

  <% end %>

In the example above, which works, I had to say @album.id in the form_tag but in the text_field I had to say :album. I keep confusing these in my views and never really know whether to use an @ sign or a symbol. Is there a simple rule that could make it clear what to use when?

+5  A: 

The @ symbol before a variable name refers to an instance variable in the current class. The : (colon) prefix creates a Symbol. In your example, @album.id is sending the id of the @album instance variable to form_tag, allowing form_tag to read in that object from the database and populate the form fields with the appropriate data from that object. The symbols you pass in the text_field methods are what form_tag uses to access specific properties on the object it creates from the database. It then puts the values of those properties into the text fields it generates.

Marc W
So the text_field doesn't know about the album just because it's enclosed by the form_tag which already has a reference to it. As Radar is saying, form_for would be a solution to this repetition. I think I'm understanding this now. Thanks for the explanation.
pez_dispenser
+4  A: 

I'm going go off on a tangent here for a moment, but bear with me.

Firstly, I recommend that you use RESTful routing as this gives you access to some of Rails better methods and operations such as being able to do:

form_for(@album) do |f|

and having it work out where you want to go based on the #new_record? state of that object.

Secondly, with the new form_for in place, you'll be able to DRY up your views by doing:

<%= f.text_field :title %>

instead of:

<%= text_field :album, :title %>

And finally the explanation of why a variable is defined with an @ sign before it in Rails, also known as "instance variables":

When you define an instance variable in Rails it is available inside that instance for the entire request where the "instance" is the ActionController and ActionView chain of methods that get called to do all the rendering and so on for you. Defining it as an instance variable will make it available in your controller, any method you call after defining it in the controller, your helpers, your views and the partials rendered from either your controllers, helpers or views.

Basically, it's around for the entire request but is not accessible inside your model.

Other variable specifications are class variables (@@some_useful_thing = 1) and global variables ($some_other_useful_thing = 1) and constants (ALL_IN_UP_CASE = 1).

Ryan Bigg
Thanks. I have to look into REST. Working on some tutorials on Rails 1.1.6 and haven't gotten to that yet. So, with form_for, text_field(:album, :title) is not necessary because the :album name is already known about since f.text_field is part of the form that you reference with do |f|. I think I get it. Thanks.
pez_dispenser