Forum: Ruby on Rails how to pass parameters with remote_function

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Mk 2. (Guest)
on 2009-05-23 23:01
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| %>
  <li class="link" onclick="<%= remote_function(:update => "album_box",
:url => { :action => :list_albums }, :with => "id=#{artist.id}") %>">
  <%=artist.name%></li>
<%end%>

and in the corresponding controller:

def list_albums
         @albums=Album.find(params[:id])
         @albums=@albums.sort { |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???
Mike R. (Guest)
on 2009-05-23 23:21
(Received via mailing list)
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
Mk 2. (Guest)
on 2009-05-23 23:28
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"? ;)  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.

<li><%=link_to artist.name, :action => "list_albums", :find_id =>
artist.id %></li>

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.
Mk 2. (Guest)
on 2009-05-23 23:34
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
Mike R. (Guest)
on 2009-05-23 23:36
(Received via mailing list)
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.
Mike R. (Guest)
on 2009-05-23 23:38
(Received via mailing list)
> @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}'")
Mk 2. (Guest)
on 2009-05-24 00:01
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. (Guest)
on 2009-05-24 00:10
(Received via mailing list)
On Sat, May 23, 2009 at 1:01 PM, Mk 27
<removed_email_address@domain.invalid> 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. ------------------------ removed_email_address@domain.invalid
Mk 2. (Guest)
on 2009-05-24 00:24
Hassan S. wrote:

> Nope, nothing to do with Ruby -- HTTP request parameters are
> *always* strings.

That makes sense.

Thanks much everyone!
Mike R. (Guest)
on 2009-05-24 02:48
(Received via mailing list)
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.
Mk 2. (Guest)
on 2009-05-24 03:26
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?
Marnen L. (Guest)
on 2009-05-24 04:06
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
removed_email_address@domain.invalid
Mike R. (Guest)
on 2009-05-24 09:11
(Received via mailing list)
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-
This topic is locked and can not be replied to.