I recently started working on a project which involves ruby on rails/javascript/jquery. I am very new to all this. The part I am involved is like this. User clicks on a button. A dialog will open, where user will enter a term to search. With that term, I am will be constructing an URI by looking at an xml. Then I will do a REST call. The response will be a XML file. I will be parsing it and displaying data in the same dialog where user entered term to search.
I am using JQuery to create a dialog. And I am doing parsing and REST call part in ruby code (Helper class). I am not using models and controller for my part. Now I need to send data from helper method to erb file where I will be displaying data as a table. Output will be like this
string11 string12 string13
string21 string22 string23
string31 string32 string33
. . .
. . .
For now, in ruby code I have create 3 arrays for every column. I am not sure on how to send data from ruby to html/javascript. If there is better way to do this then let me know. For ex: instead of sending as 3 separate array, is it better to send as xml/json? Or any other suggestions will be really helpful. Mainly I am not understanding on how to send this data to the erb file. Thank you in advance.
Edit: Adding a sample code
Javascript/Jquery -
On button click, I want to call a ruby method in erb file
Ex: <%= getUserList%>
erb file is also having other javascript/html code to display other stuffs.
And in helper method I have getUserList method
def getUserList(search)
uri = create_url(search)
#doc = Nokogiri::HTML(open(uri))
//Doing parsing and other stuffs here
//creating 3 array as mentioned above which needs to be displayed
end
I want above arrays to be displayed. I am not sure on how to send these arrays to the erb file which invoked this method
In your controller:
def users
respond_to do |format|
format.js do
render(:js => "callback(#{#users.to_json});")
end
end
end
Use something like this in your HTML to call that:
<%= link_to_remote "get users", :url => { :action => "users" } %>
More information on rendering vanilla JavaScript from a Rails action: http://guides.rubyonrails.org/layouts_and_rendering.html#rendering-vanilla-javascript
This example constructs JavaScript that calls a "callback()" function in your JavaScript code, with JSON data. Your callback function will receive a JSON string that will be easy to parse. You could also use to_xml to send XML if you really want, but parsing JSON is much simpler and faster.
You don't need a helper in this example because the JavaScript call that includes the data will come directly from your controller. There is no view template, so you don't need a helper. The best place for the code that gets the #users would be in a User model class. Not an Active Record model, just a plain model. The code that fetches the users from the remote REST API could possibly be a class method. (If you're feeling lazy then you could set #users with the REST API response right there in the "users" controller action. But that's not ideal use of Rails because the whole point of Rails is MVC.)
If you're using jQuery, then you could also use jQuery's getJSON() function so that your controller would send only the JSON data without using the callback: http://api.jquery.com/jQuery.getJSON/
Note that this is the simple kind of answer that you seem to be looking for, but this isn't really the best way to do this kind of thing for more complex applications. The best way to do this kind of thing at the moment is with something like Backbone.js. http://documentcloud.github.com/backbone/ With Backbone.js, you can define a "users" collection in JavaScript, set the REST URL of that collection (it can be a URL in your Rails app, which relays data from some other API) and then you simply call users.fetch() in your JavaScript to load the data. It's very similar to Active Record, but for the client site. It's better because it abstracts the process and allows you to update and delete records as well as simply listing them.
Related
I am building a Rails application which contains hundreds of html pages and it requires unique javascript on each page including js libraries. Rails because I am more familiar with it and also for other backend purposes.
To get an idea you can take an example of simple code conversion (eg. XML to JSON) online tools. Here the code for converting xml data to json is written in javascript on the HTML page. In my case, I want to make 100's of such tools (ie. csv to json, html to pdf etc), where each one is independent of other. I m not storing any data from these in the database but only the user info who is going to use tools. So basically all pages will be rendered from a single controller.
Please suggest me better approach for that or should I continue writing javascript on every single HTML page. Thanks.
For your case above I would like to suggest using coffeescript OOP method, below is the detail and some code for your requirement
I suggest you to use coffee with class method and then check each page with event turbolinks:load
you can check which page with name of
controller and the the method for example $(".purchase_requests.new")[0] meaning the controller is purchase_requests and the method new
also I suggest you to read brandon hilkert blog for some additional reference below is the link
sample coffeescript with check each page load
class App.PurchaseRequest
renderYourJavascript: ->
console.log "purchase request js"
$(document).on "turbolinks:load", ->
if $(".purchase_requests.new")[0] || $(".purchase_requests.edit")[0]
purchase_request = new App.PurchaseRequest
purchase_request.renderYourJavascript()
I not surely I understand your ideal. But, I think you can try to save your javascript code into database.
And you use a controller for read javascript code from database and render it as javascript file.
Example:
# routes.rb
get '/js/:file_name.js', to: 'javascripts#show'
# model
Javascript( id: :interget, name: :string, content: :text )
# controller
class JavascriptsController < ApplicationController
def show
js = Javascript.find_by_name(params[:file_name])
respond_to do |format|
format.js { js.content if js.present? }
end
end
end
I try to simply describe my ideal. Please checking again and surely it works as you want.
Hope its help.
I am using the gem gon to create json from my Rails database.
I am able to do this successfully and show the results in an alert although I would like to show it in d3.js
I have a database called users (name:string,value:integer)
I would like to pass just the values to json so these can be graphed.
Is it better to try to do this in the controller or to pass the whole table into json and then configure d3 to graph the parts I want?
Trying the former as follows
class GraphController < ApplicationController
def index
end
def data
gon.users = #users.value.as_json
#users = User.value
end
end
gives me the error:
NoMethodError in GraphController#data
undefined method `value' for nil:NilClass
and this highlights the line
gon.users = #users.value.as_json
Im not quite sure how to graph the values I want
UPDATE
So on recommendation I have now ditched gon and reverted back to creating json the old fashioned way and then trying to call it from an ajax call.
The controller therefore looks like this:
def data
render :json => User.select('value')
end
end
and I make exactly the same call to data using the ajax as set out in the tutorial I am trying to follow here
However this doesnt show me the bar graph I want and return a hash of id and value in json format.
You're not actually loading any users from the database:
class GraphController < ApplicationController
def index
end
def data
#users = User.all
gon.users = #users.value.as_json
#users = User.value
end
end
Is it better to try to do this in the controller or to pass the whole
table into json and then configure d3 to graph the parts I want?
This is a matter of opinion but I would say that it's better to create a well thought out API which exposes your resources as JSON in a way that fits many uses.
I would also ditch gon and use plain old JSON and Ajax. Injecting data into javascript from the server via script tags is kind of an anti-pattern. It relies on globals, creates timing issues and makes your controllers coupled to the behavior of javascripts components on the page.
Applications which take the "eat your own dogfood" approach and consume their own API's tend to be better executed and far more modular.
I'm confused about ajax request in rails.
I'm submitting a form using ajax and everything was fine. Now I must handle callback, but...
Following some tutorials the hint is to add a
respond_to do |format|
format.js
end
to controler#create and then place in the views folder a "create.js.erb" with the response.
Other tutorials suggest to create a js file in the assets folder and handle the callback from the JS file.
What's the difference? And what's the right way?
Both are different ways for handling callback of Ajax request. I suggest you to use js.erb file to handle ajax callback because this file can recognize the both JS as well as Ruby code and execute.
For example,
in your controller,
def create
...
if something
#foo = true
else
#foo = false
end
in your create.js.erb, it can be done like you want to show/hide some div based on the #foo value, you can write like,
<% if #foo %>
// do something with JS code
<% else %>
// do something else
<% end %>
While if you create a JS file in assets folder then you will not be able to write condition like above because it is a pure JS file and creating js.erb is an easy way to handle ajax response.
They are two very different approaches. For example, assume that all you want to do is display a message confirming the user's submission. If you go down the create.js.erb route then that file might look something like
$('#message').text('<%= j #message %>')
The response to your ajax request is a bit of javascript that does the required changes to the ui. jQuery executes that javascript when it receives it and your javascript doesn't have any visibility into what the response might do.
The other approach would be for your controller just to render some data. This could either be some JSON describing the results of the submission, or a block of html. For example your controller might do
render json: {status: 'success', message: 'Thank you for your submission'}
The javascript making the xhr might look like
$.ajax('/some_url', {dataType: 'json'}).done(function(data){
//data is the json your controller sent
$('#message').text data.message
});
or if you were rendering html
$.ajax('/some_url', {dataType: 'html'}).done(function(data){
//data is the html your controller sent
$('#message').html data
});
So in this case it's your javascript that decides what to do with the returned data.
Personally I dislike the create.js.erb route - I find it makes my javascript harder to read: I can't tell from looking at my form submission code what can/may happen in this callback.
It's also much harder to test if controllers are producing a blob of something that needs to be executed in a different language and its much harder to test your javascript if there are places where it executes arbitrary code sent to it.
I much prefer it behaving like an api, returning structured data, that the client can act appropriately on (the client might not even be a browser all the time, it could be a mobile app).
With ASP.NET MVC you have the possibility to return a JSONResult.
return JSON(new { View = RenderViewAsString("MyView", model), wasSuccessful = true})
As you can see my JSON object will have HTML and some data. The idea behind this is to use strongly typed HtmlHelpers in the MVC view and making only one request to the server instead of multiple ones.
Is it approperiate to mix a JSON object with HTML?
It is certainly effective and will get the job done quickly.
However, if you find yourself getting back ready-made HTML renders from the server together with other data a lot, or if you end up digging into the HTML received to perform "adjustments" before inserting it into the page then you should start looking into client-side templating instead. This way the server can return just the data as JSON and the client will take up the task of rendering the data into HTML independently.
I followed Hartl's Rails tutorial where he does Ajax using RJS and sending javascript in the response to be executed on the client side to edit the DOM.
But what do you do if you want just JSON sent in the response and not send javascript. This also means the javascript to manipulate the DOM should already be in the html file on the client. Is there a tutorial as good as Hartl's book on how to do this in Rails. Presumably it would use Jquery and some other stuff maybe that I've not heard of to make the code not be a million lines?
My best attempt at an answer is that it really depends on the scope and complexity of what you're trying to achieve. Generally, JSON shows up in views. If your application does not require you to dynamically retrieve JSON, that is, you can load it all when the view is initially rendered, then you can set an instance variable in your view's controller like so
#my_json = some_object.to_json()
Then, your instance variable is available in your view
<script type = 'text/javascript'>
var theJSON = <%= #my_json %>
</script>
Now, your data is available in the DOM, parsed nicely into JSON.
If your application requires you to dynamically retrieve JSON after the controller/view are loaded, then you should probably look into using AJAX to hit a particular controller's method that returns the JSON that you desire.
Here's a good RailsCast that can hopefully help you along your way Passing Data to Javascript
You should take a look at Ajax in Rails 3.1 - A Roadmap.