skwidbreth
skwidbreth

Reputation: 8404

Rails - passing a JSON from a view into a controller

In my Rails app, I would like to pass a Javscript array into the new action controller - the array is created from user input in one of the other views, and is composed of JSONs. What is the best method to a) pass the array of JSONs to the controller, and b) parse the array in the controller so that I can do things like get the array length, render the JSONs into the new view, etc.?

As I have built it, the app works fine, but I can see that the way that I have done things will cause problems as I continue to develop it.

Currently, my action controller looks like this:

def new

    x = Integer(params[:total_inserts_param])

    @report_group = Array.new
    x.times do
      @report_group.push(Report.new)
    end
end

where total_inserts_param is a count of the array length calculated in the preceding view and passed in via URL, while the actual content of the JSONs are passed between the views via stringified localStorage objects; the content of those objects is parsed out and inserted into the variable number of form input fields in the new view generated by the controller. This is certainly one way to pass data around a Rails app, but I'm pretty sure it's not a very good way!

I would much rather get the array into the controller, generate a Report.new for each JSON in the array, then populate the input fields created by the controller with the attributes of the JSONs.

I'm fairly new to Rails, so any insight into how to approach this would be much appreciated.

Upvotes: 2

Views: 1791

Answers (1)

7stud
7stud

Reputation: 48599

What is the best method to

a) pass the array of JSONs to the controller,

the array is created from user input in one of the other views,

Why not submit that form to the target action, then use ruby to assemble the data into an array? If that isn't an option, you can use javascript to send an ajax request to your rails app. Here it is using coffeescript and jquery:

window.my_func = () ->  #`window` is needed if you call the function from another file  

  array = [1, 2, 3]
  text = JSON.stringify { my_array: array }

  ajax_settings = 
    type: "post",
    url: 'http://localhost:3000/dogs/dostuff', 
    data: text,  
    contentType: "application/json",
    success: (response) -> 
        $("#result").html(response)

  $.ajax(ajax_settings)

When you write jquery code, there are so many annoying braces and parentheses, you should consider using coffeescript instead:

coffee script syntax
coffee script syntax and jquery

That coffeescript goes in your app/assets/javascript/controller_name.js.coffee file, which is automatically created by rails when you create a controller. In my case, I used a controller named DogsController, so the coffeescript file is app/assets/javascript/dogs.js.coffee.

Then, in your application.html.erb layout, you include the one big minified js file that rails creates from all the individual js files, like this:

<!DOCTYPE html>
<html>
<head>
  <meta charset="ISO-8859-1">
  <title>Restauranteur</title>
  <%= stylesheet_link_tag    "application", media: "all" %>
  <%= javascript_include_tag "application" %>  <**** HERE *****
  <%= csrf_meta_tags %>
</head>
<body>

<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>

<div>Application Layout</div>

<div>
  <%= yield %>
</div>

<%= debug params %>
<%= debug session[:allowed] %>
</body>
</html>

To call my_func() in one of your views, you just need to write:

<script>
my_func();
</script>

b) parse the array in the controller so that I can do things like get the array length

Ruby has a standard library module for converting JSON text into a ruby hash so that you can easily retrieve the data:

http://ruby-doc.org/stdlib-2.3.1/libdoc/json/rdoc/JSON.html#method-c-5B-5D

However, in your rails app you don't even need to write any code to convert the JSON text into a hash: in your jquery ajax request if you specify the contentType to be "application/json", then rails will automatically convert the JSON text in the request into a hash, which will be available in params:

{"my_array"=>[1, 2, 3], "controller"=>"dogs", "action"=>"dostuff", "dog"=>{}}  

Upvotes: 1

Related Questions