Sunday, June 9, 2013

Ruby on Rails: Working between Ruby and JavaScript Methods

In an attempt to help a friend with a Ruby project, I needed to become familiar with the Rails' way of doing things. Never thought I'd touch the stuff till about two days ago. I must say, that was quite the new experience for me - as I have never programmed before between three different scripting languages under the same project. (Ruby, JavaScript, and HTML5, if that counts)

Anyhow, I ran into a nerve-wrecking conflict in this development voyage: "calling a Ruby method from JavaScript!"

I had probably spent at least 15 hours strait trying to find the answer to this, at the same time as attempting to understand what lines of script did and why I continuously received errors or broken functions - even though my code looked identical to that which I tried from online forums (including the 'read-on' bug-fixes down the forums). FINALLY, today, I believe I stumbled upon a bit o' luck as things were starting to fall into place and just work the way I wanted it to!




  • First things first that I found often in my digging: 'know where an action should be implemented.' Ruby is to Server-Side as JavaScript is to Client-Side. All data on the client-side's page should be gathered and assembled into a 'packet' sent to the server-side method(s).
  • Ajax makes things easier (in my view).

In this example, I will show you how I successfully called a Ruby method from JavaScript.

My Environment:
Hardware: HP Z1 | Xeon | Quadro 500 | 4DDR3
OS/Version: Windows 7 Professional 64-bit
Ruby Version1.9.3p392
Rails Version3.2.13
Browser/VersionChrome 27.0.1453.110 m

  1. In your console, type: rails new your_project_name followed by cd your_project_name
  2. In your console, type: rails generate controller home index
  3. Navigate to app > views > home and open index.html.erb in Notepad (or preferred editor)
  4. Navigate to config and open routes.rb in Sublime Text 2 (or preferred editor)
  5. Navigate to app > controllers and open home_controller.rb in Sublime Text 2 (or preferred editor)
  6. In index.html.erb, add the following lines:

  7. <script type="text/javascript">
    function func()
    {
        // get user input from text field
        nm = $('input[id=numeric]').val();
        // call ruby method and send input as a 'data' parameter
        // {data:nm} is the equivalent to :data => nm
        // and can also be written as {value:nm} or {myinput:nm}
        $.post("fetchInput", {data:nm}, function(data)
        {
            alert(data);
        });
    }
    </script>
    
    <%= text_field_tag("numeric", "0", :size => 1) %>
    <!-- This button invokes a JavaScript method instead of a Ruby method as a means of easy and clean code implementation -->
    <%= link_to "<button>Submit</button>".html_safe, 'javascript:void(0);', :onclick => "func()", :id => "button_id", :class => "button_class" %>
  8. In routs.rb, add the following lines:

    your_projectname::Application.routes.draw do
        root :to => "home#index"
    
        # as of Rails 4, match has become deprecated
        # the alternative would be to use key-words 
        # appropriate for the task in this case:
        # post '/fetchInput' => 'home#fetchInput'
        match '/fetchInput' => 'home#fetchInput', :as => 'fetchInput'
    end
  9. In home_controller.rb, add the following lines:

    class HomeController < ApplicationController
    
        def index
            # code executes here on page-loading     end     def fetchInput
            # get variable information passed to this method         # again, :data can also be written as :value or :myinput         # respective to how you passed it in through ajax         # ie: :data from {data:nm}          tokens = params[:data]
            # this line returns the method result as a text object         render :text => tokens     end
    end
  10. In your console, type: rails server
  11. Enter a value into the text field and then click the button to see what happens. If all goes well, a popup window will appear containing the text information you entered.

No comments:

Post a Comment