Ramaze and Ajax

65 views
Skip to first unread message

Scott LaBounty

unread,
May 29, 2009, 11:35:03 PM5/29/09
to ram...@googlegroups.com
I'm trying to do a simple Ajax test with Ramaze starting with code found here: http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery#Rate_me:_Using_Ajax

Here's a snippet that does my post and gets the return value:

<<
        $.post("rate", {rating: $(this).html()}, function() {
            // format result
            var result = [
            "Thanks for rating, current average: #{@rating}",
            ];
            // output result
            $("#rating").html(result.join(''));
        } );

>>

And here's the rate() method from my controller:

<<
    def rate
        Ramaze::Log.debug "Enter rate"
        if request.post?
            Ramaze::Log.debug "Rating selecte = #{request[:rating]}"
            @rating = request[:rating]
        end
    end

>>

Here, for my first attempt anyway, I'm just trying to pass back in the number I selected. I can see the number getting passed to the rate() method find, but how do I get it back into the view? You can see I'm trying to set the @rating variable to do it and that's not working, so what should I do?

Thanks,

--
Scott
http://steamcode.blogspot.com/

Gavin Kistner

unread,
May 30, 2009, 12:21:44 AM5/30/09
to ram...@googlegroups.com
On May 29, 2009, at 9:35 PM, Scott LaBounty wrote:
> $.post("rate", {rating: $(this).html()}, function() {
> // format result
> var result = [
> "Thanks for rating, current average: #{@rating}",
> ];
> // output result
> $("#rating").html(result.join(''));
> } );

You seem to be confusing:
a) JavaScript with Ruby, and
b) server-side scripting with client-side scripting.

What you have happening right now is:
a) Your web browser JavaScript code is called invoking the $.post()
function.
This sends an HTTP request to the server.
b) Your Ramaze 'rate' action is called.
This happens to set a @rating instance variable in the Ruby
environment on the server.
Then is creates an HTTP response with some contents (possibly
@rating.to_s) and sends it back to your web browser.
c) Your web browser gets the response and, through the miracle of
jQuery, invokes your anonymous callback function.
Therein you construct a string called result that happens to look like
it has Ruby interpolation in it.

Your web browser has no way to access instance variables from the
server, possibly thousands of miles away.

Perhaps try something like:

$.post( "/rate", { rating: $(this).html()}, function( resultObject,
status ){jax
// Assumes you're using Safari, Chrome, or Firefox with Firebug
installed
console.dir( resultObject );
}, 'json' );

...

def rate
if request.xhr? # came from ajax request
"{ rating: #{request[:rating].to_i} }"
else
request[:rating].to_s
end
end

James Britt

unread,
May 30, 2009, 12:24:04 AM5/30/09
to ram...@googlegroups.com
Scott LaBounty wrote:

> And here's the rate() method from my controller:
>
> <<
> def rate
> Ramaze::Log.debug "Enter rate"
> if request.post?
> Ramaze::Log.debug "Rating selecte = #{request[:rating]}"
> @rating = request[:rating]

Is this actually a symbol, or a string (i.e. request['rating']) ?


--
James Britt

www.jamesbritt.com - Playing with Better Toys
www.ruby-doc.org - Ruby Help & Documentation
www.rubystuff.com - The Ruby Store for Ruby Stuff
www.neurogami.com - Smart application development

Gavin Kistner

unread,
May 30, 2009, 1:11:52 AM5/30/09
to ram...@googlegroups.com
On May 29, 2009, at 10:21 PM, Gavin Kistner wrote:
> Perhaps try something like:
>
> $.post( "/rate", { rating: $(this).html()}, function( resultObject,
> status ){jax
> // Assumes you're using Safari, Chrome, or Firefox with Firebug
> installed
> console.dir( resultObject );
> }, 'json' );
>
> ...
>
> def rate
> if request.xhr? # came from ajax request
> "{ rating: #{request[:rating].to_i} }"
> else
> request[:rating].to_s
> end
> end

Let's try that again without my 8-month old climbing all over the
keyboard:

$.post( "/rate", {rating:$(this).html()},
function( resultObject, status ){

//resultObject will be a JS object (aka Hash)
if (status=="success"){
// Safari, Chrome, or Firefox with Firebug installed

Max A

unread,
May 30, 2009, 11:22:25 AM5/30/09
to Ramaze
FYI, checking the status of the request is sort of pointless, since
with the non-$.ajax ajax functions, the callback is an "onsuccess"
callback anyway. Even says so at http://docs.jquery.com/Ajax/jQuery.post
:)

Max

Scott LaBounty

unread,
May 30, 2009, 1:08:07 PM5/30/09
to ram...@googlegroups.com
Gavin,

Thanks for your time (and your 8 month old's).

I guess what I'm really trying to do it see the simplest Ramaze/Jquery/Ajax sample and I was just using the code that was available to try to get it to work. With the code you've supplied, what should I see on the console? What is actually returned in the resultObject? It looks like a ruby string but what is it when it gets to the function (you seem to imply a hash, would it always be that)? How do I get the string back out?

I'm pretty new to web programming and appreciate the help.

Scott
--
Scott
http://steamcode.blogspot.com/

Scott LaBounty

unread,
May 30, 2009, 1:31:34 PM5/30/09
to ram...@googlegroups.com
Gavin,

One more thing ... do I need to do something to resume running after the console command (yes, new to Firebug too).

Scott
--
Scott
http://steamcode.blogspot.com/

Scott LaBounty

unread,
May 30, 2009, 7:39:10 PM5/30/09
to ram...@googlegroups.com
OK, it looks like JS means JSon and not JavaScript. When I look at the console.debug(resultObject), I see the entire page and not just what should have been passed back from the rate() method.

I'll keep at it.

Thanks,

Scott
--
Scott
http://steamcode.blogspot.com/

Gavin Kistner

unread,
May 30, 2009, 8:31:45 PM5/30/09
to ram...@googlegroups.com
On May 30, 2009, at 11:08 AM, Scott LaBounty wrote:
> I guess what I'm really trying to do it see the simplest Ramaze/
> Jquery/Ajax sample and I was just using the code that was available
> to try to get it to work. With the code you've supplied, what should
> I see on the console? What is actually returned in the resultObject?
> It looks like a ruby string but what is it when it gets to the
> function (you seem to imply a hash, would it always be that)? How do
> I get the string back out?

Per the documentation for the jQuery $.post() function[1], when the
fourth parameter is the string "json", the data returned from the web
server as the response—which, aside from http headers, is just a big
blob of bytes that might be html, javascript, a binary graphic, etc.—
is interpreted as a JSON data object. This sets the first parameter
passed to your function callback as a JavaScript object, which is
similar to a Ruby Hash. (In a JS Object, all keys are strings.
myObject.foo is the same as myObject["foo"], and myObject[1] is the
same as myObject["1"].)

Dumping content to the FireBug console does not interrupt the
JavaScript or HTML processing. You don't need to resume from it.

console.debug( "foo" ) is like Ramaze::Log.debug("foo"), except of
course that it comes out in a different spot. console.dir() is a
convenience function that, given a JS object, provides an interactive
hierarchical representation of it.

If that is dumping out a big string that looks like the page, my guess
is that the output string of your "rate" action is getting wrapped in
a Ramaze layout. Does that seem likely?

The simplest possible example is not to supply "json" as the fourth
parameter to $.post(), in which case the first parameter to your
callback function should just be the text sent by your action.
Something like:


$.post( "/rate", { foo: "bar" }, function( response ){
console.log( "Rate sent back: " + response );
} );

-_-_-_-_-_-_-

def rate
# Make sure this action doesn't use a layout
"OH HAI! You sent me: #{request['foo'}"
end


Thanks to Max A for pointing out that my test for the success status
of the AJAX is apparently superfluous when using $.post()


[1] http://docs.jquery.com/Ajax/jQuery.post#urldatacallbacktype

Scott LaBounty

unread,
May 30, 2009, 10:18:12 PM5/30/09
to ram...@googlegroups.com
Gavin,

I think you found it with the layout. Now ... (you've got to be getting tired of me by now) ... I tried doing a deny_layout for rate(), but I get a:

start.rb:7:in `<class:MainController>': undefined method `deny_layout' for MainController:Class (NoMethodError)

Did this get removed in the new Ramaze?

Scott
--
Scott
http://steamcode.blogspot.com/

Scott LaBounty

unread,
May 30, 2009, 10:24:11 PM5/30/09
to ram...@googlegroups.com
Yep, everything works if I do away with layouts.

Thanks so much for your help. Head on back to play with your little one now.

Scott
--
Scott
http://steamcode.blogspot.com/

Gavin Kistner

unread,
May 30, 2009, 10:33:24 PM5/30/09
to ram...@googlegroups.com
On May 30, 2009, at 8:18 PM, Scott LaBounty wrote:
> I think you found it with the layout. Now ... (you've got to be
> getting tired of me by now) ... I tried doing a deny_layout for
> rate(), but I get a:
>
> start.rb:7:in `<class:MainController>': undefined method
> `deny_layout' for MainController:Class (NoMethodError)
>
> Did this get removed in the new Ramaze?

I believe so. See manveru's first response to my long initial post for
various ways that you can control whether or not an action (or a
particular request for an action) will use a layout:

http://groups.google.com/group/ramaze/tree/browse_frm/thread/ee345c4f7bf63a38/e68842cdfb120806?rnum=1&_done=%2Fgroup%2Framaze%2Fbrowse_frm%2Fthread%2Fee345c4f7bf63a38%3Ftvc%3D1%26#doc_14ddeebcd8c190e1

Scott LaBounty

unread,
May 30, 2009, 11:00:25 PM5/30/09
to ram...@googlegroups.com
I'll give that a shot. Once again, thanks for all your help.

Scott
--
Scott
http://steamcode.blogspot.com/

jesusisramaz...@geoshell.com

unread,
May 31, 2009, 8:39:29 PM5/31/09
to ram...@googlegroups.com
2009/5/30 Scott LaBounty - slab...@gmail.com:

>> > `deny_layout' for MainController:Class (NoMethodError)
>> >
>> > Did this get removed in the new Ramaze?
>>
>> I believe so. See manveru's first response to my long initial post for
>> various ways that you can control whether or not an action (or a
>> particular request for an action) will use a layout:

> I'll give that a shot. Once again, thanks for all your help.

FWIW, I added a Layout Helper to Ramaze, and my patch was accepted
into the master branch. I made it because of there have been several
people in IRC wondering just what happened to 2009.03 style layouts.
:) The new Layout Helper is a convenience wrapper for the more
powerful, but perhaps more low-level 2009.05 layout method.

I think manveru is aiming to get a new Ramaze release out this coming
week, but you can look over the Layout Helper now, in case you are
willing to try the git version of Ramaze:

http://github.com/manveru/ramaze/blob/a6345820c5ac949a95eb3385881c9cba995b6a77/lib/ramaze/helper/layout.rb

I also added specs that demonstrate usage even more.


--
Pistos
http://blog.purepistos.net

Scott LaBounty

unread,
May 31, 2009, 11:14:14 PM5/31/09
to ram...@googlegroups.com
OK, thanks to everyone, especially Gavin, I got everything working. However, in trying to extend it, I'm running into problems. If I have:

            "{ choice: #{request['choice']} }"

returned from my rate() method pretty much the same as I showed earlier, everything works fine with the following jQuery:

                $.post("/choose", {choice: $(this).html()},
                    function(resultObject, resultStatus) {
                        console.dir(resultObject)

                        // format result
                        var result = [
                            "<br>Thanks for choosing. You chose: ", resultObject.choice, " at ", resultObject.time
                        ];
                        console.debug(result)
                        // output result
                        $("#ajaxContainer").append(result.join(''));
                    },
                    'json' );

Note what I'm trying to add is the time in the result. So I tried making the return value:

            "{ choice: #{request['choice']}, time: #{Time.now} }"

and nothing seems to work (console.dir() doesn't display anything result doesn't even look to get calculated. Am I missing something somewhere with the JSON? Something else?

Scott
--
Scott
http://steamcode.blogspot.com/

Michael Fellinger

unread,
Jun 1, 2009, 12:08:24 AM6/1/09
to ram...@googlegroups.com

Time#to_s is not valid JSON, and JSON has no type that represents Time
directly. You will have to convert it to a Date object in the JS client.
Doing that is easiest if you go via a unix timestamp (Time#to_i). In Ruby you
can use the Time::at method to create a Time instance from a unix timestamp
although you'll loose all sub-second precision.

require 'json'; require 'time'
# true

time = Time.now
# 2009-06-01 12:58:59 +0900

time.to_s
# "2009-06-01 12:58:59 +0900"

JSON.parse %[ { "time": #{time} } ]
JSON::ParserError: 598: unexpected token at '{ "time": 2009-06-01 12:58:59 +0900 } '
from /home/manveru/.gem/ruby/1.9.1/gems/json-1.1.3/lib/json/common.rb:122:in `parse'
from /home/manveru/.gem/ruby/1.9.1/gems/json-1.1.3/lib/json/common.rb:122:in `parse'
from (irb):6
from /usr/bin/irb:12:in `<main>'

JSON.parse %[ { "time": #{time.to_i} } ]
# {"time"=>1243828739}

puts({:time => time}.to_json)
{"time":"2009-06-01 12:58:59 +0900"}

# and here we play a bit with (de)serialization

time1, time2 = Time.now, Time.now
# [2009-06-01 13:07:15 +0900, 2009-06-01 13:07:15 +0900]
time1 == time2
# false
Time.at(time1.to_i) == Time.at(time2.to_i)
# true
time1.to_i
# 1243829235
time2.to_i
# 1243829235

>
> Scott
>
> On Sun, May 31, 2009 at 5:39 PM,
> <jesusisramaz...@geoshell.com>wrote:
>
> >
> > 2009/5/30 Scott LaBounty - slab...@gmail.com:
> > >> > `deny_layout' for MainController:Class (NoMethodError)
> > >> >
> > >> > Did this get removed in the new Ramaze?
> > >>
> > >> I believe so. See manveru's first response to my long initial
> > >> post for various ways that you can control whether or not an
> > >> action (or a particular request for an action) will use a layout:
> >
> > > I'll give that a shot. Once again, thanks for all your help.
> >
> > FWIW, I added a Layout Helper to Ramaze, and my patch was accepted
> > into the master branch. I made it because of there have been
> > several people in IRC wondering just what happened to 2009.03 style
> > layouts. :) The new Layout Helper is a convenience wrapper for the
> > more powerful, but perhaps more low-level 2009.05 layout method.
> >
> > I think manveru is aiming to get a new Ramaze release out this
> > coming week, but you can look over the Layout Helper now, in case
> > you are willing to try the git version of Ramaze:
> >
> >
> > http://github.com/manveru/ramaze/blob/a6345820c5ac949a95eb3385881c9cba995b6a77/lib/ramaze/helper/layout.rb
> >
> > I also added specs that demonstrate usage even more.
> >
> >
> > --
> > Pistos
> > http://blog.purepistos.net
> >
> > >
> >
>
>

--
^ manveru

Scott LaBounty

unread,
Jun 1, 2009, 9:51:49 AM6/1/09
to ram...@googlegroups.com
Michael,

Thanks for responding. In the case above, isn't the time just represented as a string? Does the JavaScript side try to do something with it to make it "not a string"?

Also, I tried something similar to:

"{ choice: #{request['choice']}, test: test }"

with pretty much the same result. Is the second "test" not interpreted as a string?

Thanks again for your and everyone's patience with my questions.

Scott
--
Scott
http://steamcode.blogspot.com/

Scott LaBounty

unread,
Jun 1, 2009, 10:28:55 AM6/1/09
to ram...@googlegroups.com
OK, I played with it a bit more and it looks like if I enclose the "test" case in double quotes then everything works fine. Same if I pass it an integer with no quotes (hadn't tried that before). Putting the time in quotes now passes it correctly, but it doesn't show up correctly with the following:


                            "<br>Thanks for choosing. You chose: ", resultObject.choice, " at ", resultObject.time

from:

            "{ choice: #{request['choice']}, time: \"#{Time.now}\" }"

I do see it showing up from my console.dir as:

"2009-06-01 07:26:22 -0700"

Getting closer anyway. Thanks for all the help.

Scott
--
Scott
http://steamcode.blogspot.com/

Scott LaBounty

unread,
Jun 1, 2009, 11:30:18 AM6/1/09
to ram...@googlegroups.com
Looks like I must not have saved something correctly or something else silly. Looks like it all works now. Thanks for pointing me in the right direction.

Scott
--
Scott
http://steamcode.blogspot.com/

Scott LaBounty

unread,
Jun 1, 2009, 2:19:33 PM6/1/09
to ram...@googlegroups.com
Finally ...

Thanks to everyone's help, I have the following blog post about this.

http://steamcode.blogspot.com/2009/05/ramaze-jquery-and-ajax.html

Hopefully, this will help others as you all have helped me.

Take a look and let me know of errors or omissions.

Scott
--
Scott
http://steamcode.blogspot.com/
Reply all
Reply to author
Forward
0 new messages