创建url查询参数并传递给Rails控制器

时间:2017-05-24 16:59:30

标签: ruby-on-rails

我的问题涉及将值从JS传递到控制器,然后使用它们来查询和返回一些输出数据。这些值是UI中选择的结果:

<!-- Select car make -->
<ul id = "make">
   <% Car.all.each do |c| %>
      <li><%= link_to c.make, todos_data_path(:make_id => c.id), :method => :post, remote: true %></li>
   <% end %></ul>

<!-- Select car body -->
<ul id = "body">
   <% Type.all.each do |t| %>
       <li><%= link_to t.name, todos_data_path(:body_id => t.id), :method => :post, remote: true %></li>
   <% end %></ul>

在JS中提取选定的值:

var make = $('#make').text();    
var body = $('#body').text();  

在搜索之后,我从post学到了一个人不能直接将变量从JS传递给Rails。而是通过将值作为参数附加到控制器中来将值传递给控制器​​。根据我的理解,我需要的是三个基本步骤:

步骤1:使用JavaScript创建查询字符串参数。 way执行此操作的一种方式:

var url = "http://www.myapp/todos/data?" + $.param({make_id: make, body_id: body})
//http://www.myapp/todos/data?make_id=4&body_id=3

步骤2:将查询字符串附加到网址。 在较早的question之后,可以通过以下方式将查询字符串附加到url:

window.open(url, "_self");

步骤3:运行url字符串并在控制器中使用params。

我的路线:

resources : todos, only: [:index, :new, :create , :destroy]
get '/todos/data (:make_id)(:body_id)' => 'todos#data'

控制器:

def data
    @make = params[:make_id]
    @body = params[:body_id]

    @vehicles = Vehicle.where(make: @make, body: @body )

    respond_to do |format|
      format.html{ redirect_to root_path }
      format.js { }
    end
end

在url中运行字符串后的输出:

Started GET "/todos/data?make_id=2&body_id=3" for 10.240.0.185 at 2017-05-24 12:55:58 +0000
Processing by TodosController#data as HTML
Parameters: {"make_id"=>"2", "body_id"=>"3"}
Redirected to http://myapp/
Completed 302 Found in 4ms (ActiveRecord: 0.6ms)

似乎一切正常,直至redirect_to root_path。我希望执行format.js { },因为我的目标是渲染data.js.erb。如何使操作响应JS格式而不是HTML?我尝试在路由get '/todos/data(:make_id)(:body_id)' => 'todos#data', :defaults => { :format => 'js { }' }中指定,但它生成了未知的格式错误。

我已经公布了我想要做的事情的整个过程,以明确我想要实现的目标,并且可能会得到关于如何以不同方式完成整个事情的建议。

编辑: 我还需要展示我的todo.js

$( document ).on('turbolinks:load', function() {
    $('#make').on('click', 'li', function (event){
        event.preventDefault();
        $('.active').removeClass('active');
        var text = $(this).text();
        $(this).addClass('active');
    });

    $('#body').on('click', 'li', function (event){
        event.preventDefault();
        $('.active').removeClass('active');
        var text = $(this).text();
        $(this).addClass('active');
    });
});

1 个答案:

答案 0 :(得分:0)

当您执行window.open(url, "_self");时,它正在请求作为html get请求。你为什么不用ajax?

 $.ajax({
   url: url,
   method: "GET",
   dataType: "script", /*optional*/
   success: function(response){
    console.log(response)
   }
 })

选项2:

$("a").on("click", function(){
   $.ajax({
      url: "http://www.myapp/todos/data",
      type: "get",
      dataType: "script",
      data: { 
        make_id: make, 
        body_id: body 
      },
      success: function(response) {
        console.log(response);
      },
      error: function(xhr) {
        //Do Something to handle error
      }
  });
  return false;
})

代替$("a"),使用您想要的选择器。