使用jQuery将实例从视图传递到控制器

时间:2014-05-14 00:52:29

标签: javascript jquery ruby-on-rails ruby

环境Ruby 2.0.0,Rails 4.0.3,Windows 8.1,jQuery

编辑:仅供参考,我前几天正在讨论这个问题而且我被告知解决这个问题的常用方法就是传递记录ID。当然,我会在一般情况下推荐这个解决方案。在这种情况下,正在创建记录但尚未存储记录,因此它没有ID,并且在完成所有必填字段之前不能具有ID。

我需要将对象实例从视图传递到jQuery到控制器,以便控制器使用它来使用依赖选择渲染部分。即使我只是传递一个命名对象的字符串,这个过程通常也能正常工作。但是,现在我必须实现强参数来允许更新,这需要实际的实例,而不仅仅是实例的字符串名称。

在jQuery中,我使用以下内容来获取实例,但它显然是错误的,因为它只获取实例的字符串名称。我想它可能需要序列化吗?但是,我只能得到无法序列化的字符串名称。

var car = $('select#car_year_id').attr("car");

基本问题是,如何在jQuery中检索汽车的实际实例?或者,我想,问题是,给定Ruby on Rails中的实例的字符串名称,我该如何处理实际的实例?任何一个都可能就足够了。当然,其他替代品将受到欢迎。谢谢。

表格是:

<div class="span8">
  <%= simple_form_for @car,
                      defaults: {label: false},
                      html: {class: 'form-vertical'},
                      wrapper: :vertical_form,
                      wrapper_mappings: {
                              check_boxes: :vertical_radio_and_checkboxes,
                              radio_buttons: :vertical_radio_and_checkboxes,
                              file: :vertical_file_input,
                              boolean: :vertical_boolean
                      } do |f| %>
      <%= f.input(:stock_number, {input_html: {form: 'new_car', car: @car},  autocomplete: :off, placeholder: 'Stock number?'}) %>
      <%= f.input(:year_id, {input_html: {form: 'new_car', car: @car}, collection: Year.all.collect { |c| [c.year, c.id] }, prompt: "Year?"}) %>
      <%= render partial: "makes", locals: {form: 'new_car', car: @car} %>
      <%= render partial: "models", locals: {form: 'new_car', car: @car} %>
      <input type="submit" form="new_car" value="Create Car" class="btn btn-default btn btn-primary">
  <% end %>
</div>

“make”部分是:

<%= simple_form_for car,
                    defaults: {label: false},
                    remote: true do |f| %>
    <% makes ||= "" %>
    <% if !makes.blank? %>
        <%= f.input :make_id, {input_html: {form: form, car: car}, collection: makes.collect { |s| [s.make, s.id] }, prompt: "Make?"} %>
    <% else %>
        <%= f.input :make_id, {input_html: {form: form, car: car}, collection: [], prompt: "Make?"} %>
    <% end %>
<% end %>

jQuery是:

$(document).ready(function () {
    // when the #year field changes
    $("#car_year_id").change(function () {
        // make a GET call and replace the content
        var year = $('select#car_year_id :selected').val();
        if (year == "") year = "invalid";
        var form = $('select#car_year_id').attr("form");
        if (form == "") form = "invalid";
        var car = $('select#car_year_id').attr("car");
        if (car == "") car = "invalid";
        $.post('/cars/make_list/',
            {
                form: form,
                year: year,
                car: car
            },
            function (data) {
                $("#car_make_id").html(data);
            });
        return false;
    });
});

控制器操作是:

  def make_list
    makes = params[:year].blank? ? "" : Make.where(year_id: params[:year]).order(:make)
    render partial: "makes", locals: { car: params[:car], form: params[:form], makes: makes }
  end

1 个答案:

答案 0 :(得分:1)

我找到了答案!太激动了!

有一个新的HTML结构允许您对HTML元素使用任意属性,只要名称前面带有&#34; data - &#34;。例如:

<%= f.input(:year_id, {input_html: {form: 'new_car', data-car: @car}}, collection: Year.all.collect { |c| [c.year, c.id] }, prompt: "Year?"}) %>

这在Rails中存在问题,因为Rails不喜欢符号中的连字符。但是,有一个可选的帮助器使用data:符号传递哈希,如:

<%= f.input(:year_id, {input_html: {form: 'new_car', data: { car: @car}}, collection: Year.all.collect { |c| [c.year, c.id] }, prompt: "Year?"}) %>

请参阅:Best way to use html5 data attributes with rails content_tag helper?

然后,在JavaScript中,您可以使用dataset属性来检索DOMStringMap对象,如下所示:

var element = document.getElementById('car_year_id');
var car = element.dataset.car;

请参阅:HTML5 Custom Data Attributes (data-*)

这会将汽车作为哈希对象返回,这正是我所需要的!

总体参考帮助很多:Rails 3 Remote Links and Forms: A Definitive Guide

为了完整起见,我曾经使用以下代码将哈希值转换回控制器中的对象:

car_hash = params[:car].gsub!(/":/, '" => ')
null = nil
@car = Car.new(eval(car_hash))