Form post not working


#1

Hi there,

I have this form code in a view:

<%= start_form_tag :action => “listByArtist”, :id => artist.id %>

List by Artist: <%= options_from_collection_for_select(@artists, "id", "name") %> <%= submit_tag "List" %> <%= end_form_tag %>

When I hard code the “:id” in line 1 everything works fine - in that the
listByArtist controller and view render exactly what I want.

When I use the above code with “:id => artist.id” I get this error:

undefined local variable or method `artist’

This is really frustrating, I am simply trying to pass the id of an
artist which is selected by the user, such as to list all songs by this
artist.

How can I successfully pass this artist.id?

Thanks,
A


#2

Abhinav wrote:

<%= end_form_tag %>
artist.

How can I successfully pass this artist.id?
It needs to be passed from the controller as an instance variable. Your
controller code should look something like this:

def lookup
@artist = Artist.find(params[:id])
@artists = Artist.find(:all)
end

and then you can use

<%= start_form_tag :action => “listByArtist”, :id => @artist.id %>

in your view.


#3

Alex Y. wrote:

It needs to be passed from the controller as an instance variable. Your
controller code should look something like this:

def lookup
@artist = Artist.find(params[:id])
@artists = Artist.find(:all)
end

and then you can use

<%= start_form_tag :action => “listByArtist”, :id => @artist.id %>

in your view.

Thanks Alex - I believe I am doing this already…so I guess I should
run through exactly what I have set up so far.

I have the following setup. Essentially from “list” I can call
“listByArtist” to show songs grouped by the artist selected.

What I am trying to do is pass the artist.id from the list view to the
listByArtist controller, which in turn builds an array of songs that
have the artist.id associated to them (marked below with >>>).

I placed your suggested code into the listByArtist controller, but
really all I am passing to the controller is an integer that represents
an artist…the code below works fine for the listByArtist controller
and view.

I just cant seem to pass the artist.id from the list view as I keep
getting the aforementioned error.

– Controller code –

def list
@songs = Song.find(:all, :order => “(select name from artists where
artists.id = songs.artist_id)”)
@artists = Artist.find_all
end

def listByArtist

@song = Song.find(:all, :conditions => [ “artist_id = ?”, @params[“id”] ])
@artist = Artist.find(params[:id])
end

– End Controller code –

– List View Code –

All Songs

<% @songs.each do |song| %> <% end %>

Song

Artist

<%= link_to song.name, :action => "show", :id => song.id %>

<%= song.artist.name %>

<%= start_form_tag :action => “listByArtist”, :id => @artist.id %>

List by Artist: <%= options_from_collection_for_select(@artists, "id", "name") %> <%= submit_tag "List" %> <%= end_form_tag %>

– End List View Code –

– ListByArtist View Code –

Songs by Artist

<% @song.each do |song| %> <% end %>

Song

<%= link_to song.name, :action => "show", :id => song.id %>

– End ListByArtist View Code –


#4

Alex Y. wrote:

list and listByArtist are actions, not controllers. The controller is
the class that holds those actions. At least, I assume that’s how
you’ve set this up. It would be the most sensible way, I think.

Yes that is how I have set it up…my terminology is not up to
scratch…if it isnt obvious I am very new to ruby/rails/html. :slight_smile:

I placed your suggested code into the listByArtist controller,
It should go in the list action, so that the list view has access to
@artist.

Um…I actually got it to work without adding anything into the list
action.

At least, that’s what’s wrong in theory. Looking at it, I don’t
actually see why you need :id => @artist.id in the start_form_tag call
at all… the ID is going to be provided by the select box anyway.

Yes you are right here - I have not explicityly stated the :id in other
forms and they are working fine. I was just trying to explicitly pass
this id as a brute force attempt to send the id to the listByArtist
action.

You’ll need to change the call in the listByArtist from params[:id] to
params[:artists][:id], but that’s where the value should be coming
from…

So - I now understand where I was going wrong. Thanks for your help
Alex - it has put me straight…

I removed the :id from the start_form_tag in the listByArtist view:

<%= start_form_tag :action => “listByArtist” %>

…and called the variable artist instead of artists (just cleaning up):

…and I added this to the listByArtist action:

    def listByArtist

            @song = Song.find(:all, :conditions => [ "artist_id =

?", params[:artist][:id] ])
@artist = Artist.find(params[:artist][:id])

    end

I did not change the list action as you have suggested. This did not
seem necessary to me as the only two arrays of data being used by the
list action were song and artists. So I left this alone.

I really need to learn about using a debugger to be able to quickly
establish what is going wrong.

Anyway - thank you for your help!
A


#5

Abhinav wrote:

and then you can use
“listByArtist” to show songs grouped by the artist selected.

What I am trying to do is pass the artist.id from the list view to the
listByArtist controller, which in turn builds an array of songs that
have the artist.id associated to them (marked below with >>>).
First, some terminology, just so we’re singing from the same hymn sheet.

list and listByArtist are actions, not controllers. The controller is
the class that holds those actions. At least, I assume that’s how
you’ve set this up. It would be the most sensible way, I think.

list’s view only has access to those instance variables define in the
list action. In your case, that is @songs and @artists.

I placed your suggested code into the listByArtist controller,
It should go in the list action, so that the list view has access to
@artist.

> <%= start_form_tag :action => "listByArtist", :id => @artist.id %> >

List by Artist: > > <%= options_from_collection_for_select(@artists, "id", "name") %> > > <%= submit_tag "List" %> > <%= end_form_tag %> > I don't know if this is something you might be assuming, but defining 'listByArtist' as an action for the start_form_tag call doesn't call the listByArtist action. It sets it up to be called on form submission. That's why the list action needs to define @artist for itself.

At least, that’s what’s wrong in theory. Looking at it, I don’t
actually see why you need :id => @artist.id in the start_form_tag call
at all… the ID is going to be provided by the select box anyway.
You’ll need to change the call in the listByArtist from params[:id] to
params[:artists][:id], but that’s where the value should be coming
from…