How to pass parameters with remote_function

I cannot find a complete example of this on the web.

Here’s what I’m trying to do: In a view I have a remote_function call
that right now looks like this:

<% @artists.each do |artist| %>

  • { :action => :list_albums }, :with => "id=#{artist.id}") %>"> <%=artist.name%>
  • <%end%>

    and in the corresponding controller:

    def list_albums
    @albums=Album.find(params[:id])
    @[email protected] { |a,b| a.title <=> b.title }
    end

    Either or both of these is wrong, since in the end I get a “Can’t find
    an album without id”. There is a complicating issue, too, since if I
    change the parameter name, I get “undefined local variable”.

    Anyone got a quick example of the syntax for what must be a very
    common and simple task???

    First off, have you ‘thrown’ the params hash that you get in the
    controller?

    You can paste it back here if this did not help you solve your
    problem.

    -Mike

    Mike R. wrote:

    First off, have you ‘thrown’ the params hash that you get in the
    controller?

    You can paste it back here if this did not help you solve your
    problem.

    -Mike

    Where, like “out the window”? :wink: I do not understand what you mean by
    thrown.

    Here’s something (else) strange (to me): I am trying to work this out
    now with link_remote, since that’s simpler until I get the nitty gritty.

  • <%=link_to artist.name, :action => "list_albums", :find_id => artist.id %>
  • I notice that WEBbrick output sez:

    Parameters: {“artist_id”=>“65”}

    Shouldn’t this be passed as “find_id”??? I guess I could have this
    backward, will test. Maybe I’ll also try to log output to a file in the
    controller, if rails will allow me to debug that way…

    Anyway, really the best thing for me would be an example paralleling the
    OP request.

    Okay, I got the WEBbrick output to agree with me. Here’s the line in
    the controller now, which is still wrong:

    @albums=Album.find(:all, :conditions => [:artist_id =>
    params[:find_id]])

    NoMethodError in MainController#list_albums
    undefined method `%’ for {:artist_id=>“67”}:Hash

    @albums=Album.find(:all, :conditions => [:artist_id =>
    params[:find_id]])

    Good practice for it to read like this

    @albums = Album.find(:all, :conditions => “where artist_id = ‘#{params
    [:find_id}’”)

    Well, to be honest your first post looks correct by inspection. If you
    are just posting the id though you do not necessarily need to
    use :with. You can group all the items you want within the :url block.

    Also, by saying ‘throw’, I mean that in your action in the controller
    have ‘throw params’ as the first line and then when you try to access
    that action it will output, to the screen, a trace that shows you what
    parameters are coming across from the view. Very helpful. You can keep
    throwing until you get the correct params coming across and then focus
    on fixing or writing your action code.

    Hmmm, I seem to be uncovering a more basic layer to my miscomprehension.
    Thanks people, I think your input will come in handy, but bear with me
    for a minute:

    Here’s where I got to in trying to debug (just noticed stdout in the
    controller is the server stdout, handy). Hence its long winded style:

    [in controller method]
    all=Album.find(:all)
    @albums = Array.new
    tmp=params[:find_id]
    all.each { |rec|
    if rec.artist_id == tmp
    @albums.push rec
    else puts “->#{rec.artist_id} != #{tmp}”
    end
    }

    Now, what I find mind boggling is some of the output:

    ->67 != 67
    ->67 != 67
    ->67 != 67
    ->67 != 67
    ->67 != 67
    ->67 != 67
    ->67 != 67

    WHAT THE HECK? I’m new to ruby, this seems an odd feature…I would
    guess this is about data types??!!? Both numbers are sourced from an
    sqlite INTEGER.

    Hassan S. wrote:

    Nope, nothing to do with Ruby – HTTP request parameters are
    always strings.

    That makes sense.

    Thanks much everyone!

    On Sat, May 23, 2009 at 1:01 PM, Mk 27
    [email protected] wrote:

    ->67 != 67

    WHAT THE HECK? I’m new to ruby, this seems an odd feature…I would
    guess this is about data types??!!? Both numbers are sourced from an
    sqlite INTEGER.

    Nope, nothing to do with Ruby – HTTP request parameters are
    always strings.

    If you need to compare to an integer, use params[:whatever].to_i


    Hassan S. ------------------------ [email protected]

    Furthermore, naming conventions in rails/ruby say you should not have
    a variable called tmp, temp, temporary, or any of that ambiguous
    naming.

    Also, now that you know you should be casting to_i from params, try
    using the original method I suggested

    @albums = Album.find(:all, :conditions => “where artist_id = ‘#{params
    [:find_id].to_i}’”)

    and let me know if that solved the issue. It’s really bad/wasteful to
    pull down all of your artists. Also, shorthand

    @collection = Model.find(:all) is the same as @collection = Model.all

    likewise, you can do Model.first and Model.last to get the first and
    low entry of a table!

    Good luck.

    Mike R. wrote:

    and let me know if that solved the issue. It’s really bad/wasteful to
    pull down all of your artists. Also, shorthand

    Yeah, that is what I meant by “long winded”.

    Why is there this issue with the name of a local, temporary variable?
    If the scope is only a few lines, I might as well call it “x” (which is
    why I think tmp is unambiguous: it indicates this variable is just
    that, and nothing more than that)…Is this just the normal “pick
    informative names” caveat, or is there more to it? Rails is slightly
    scary…

    Your “where =” line did not work – I may have mistyped it, but this
    seems to do:

    @albums = Album.find(:all, :conditions => { :artist_id =>
    params[:find_id].to_i })

    Most of all: Your help is much appreciated dude, THANKS!

    ps. If you have a minute, here’s a little question about what I am
    about to try: I have a list on one side with all the artists. A click
    on a list entry will put all the artist’s albums in a div box on the
    other side. Now, I want to add a menu up top with entries like “Sort
    albums by size”, but I want that to apply only to the albums that are
    currently displayed. I don’t want to produce the list again and sort it
    (since I have some more complicated plans, like allowing the user to
    build a custom list in the div box); I want to try and keep a global
    variable ($shown) and process that back in the album controller.
    Hopefully this is possible – any related tips brought to mind?

    Mike R. wrote:

    @albums=Album.find(:all, :conditions => [:artist_id =>
    params[:find_id]])

    Good practice for it to read like this

    @albums = Album.find(:all, :conditions => “where artist_id = ‘#{params
    [:find_id}’”)

    Nope. Your “good practice” is in fact more typing and more literal SQL
    for what as far as I can see is no good reason at all. Take advantage
    of Rails’ syntactic sugar and stick with the first version.

    Best,

    Marnen Laibow-Koser
    http://www.marnen.org
    [email protected]

    Note: remove the where in the string, I was typing a bit too quickly
    and that does not belong.

    I should have said my preferred practice as well. But glad everything
    worked out.

    On May 23, 5:06 pm, Marnen Laibow-Koser <rails-mailing-l…@andreas-