Hi there, I have this form code in a view: <%= start_form_tag :action => "listByArtist", :id => artist.id %> <p><b>List by Artist:</b> <select id="artist_id" name="artists[id]"> <%= options_from_collection_for_select(@artists, "id", "name") %> </select> <%= 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 -- Posted via http://www.ruby-forum.com/.
Abhinav wrote:> Hi there, > > I have this form code in a view: > > <%= start_form_tag :action => "listByArtist", :id => artist.id %> > <p><b>List by Artist:</b> > <select id="artist_id" name="artists[id]"> > <%= options_from_collection_for_select(@artists, "id", "name") %> > </select> > <%= 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?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. -- Alex
Alex Young 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 -- <h1>All Songs</h1> <center> <table border="0"> <tr> <td width="50%"><p align="center"><i><b>Song</b></i></td> <td width="50%"><p align="center"><i><b>Artist</b></i></td> </tr> <% @songs.each do |song| %> <tr> <td><p align="center"><%= link_to song.name, :action => "show", :id => song.id %></td> <td><p align="center"><%= song.artist.name %></td> </tr> <% end %> </table> <%= start_form_tag :action => "listByArtist", :id => @artist.id %> <p><b>List by Artist:</b> <select id="artist_id" name="artists[id]"> <%= options_from_collection_for_select(@artists, "id", "name") %> </select> <%= submit_tag "List" %> <%= end_form_tag %> </center> -- End List View Code -- -- ListByArtist View Code -- <h1>Songs by Artist</h1> <center> <table border="0"> <tr> <td width="50%"><p align="center"><i><b>Song</b></i></td> </tr> <% @song.each do |song| %> <tr> <td><p align="center"><%= link_to song.name, :action => "show", :id => song.id %></td> </tr> <% end %> </table> </center> -- End ListByArtist View Code -- -- Posted via http://www.ruby-forum.com/.
Abhinav wrote:> Alex Young 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 >>>).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. <snip>> <%= start_form_tag :action => "listByArtist", :id => @artist.id %> > <p><b>List by Artist:</b> > <select id="artist_id" name="artists[id]"> > <%= options_from_collection_for_select(@artists, "id", "name") %> > </select> > <%= submit_tag "List" %> > <%= end_form_tag %> > </center><snip> 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... -- Alex
Alex Young 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. :)>> 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): <select id="artist_id" name="artist[id]"> ...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 -- Posted via http://www.ruby-forum.com/.