如何通过AJAX在Rails 4中向表单添加额外字段?

3

我使用的是Rails 4。假设我有三个模型:HouseColorHouseColoring

class House < ActiveRecord::Base
  has_many :house_colorings
  has_many :colors, through: :house_colorings
  accepts_nested_attributes_for :house_colorings, allow_destroy: true
end

class Color < ActiveRecord::Base
  has_many :house_colorings
  has_many :houses, through: :house_colorings
end

class HouseColoring < ActiveRecord::Base
  belongs_to :house
  belongs_to :color
end

houses_controller.rb:

class HousesController < ApplicationController
  before_action :set_house
  ...

  def new
    @house = House.new
    @house.house_colorings.build
  end

  def create
    @house = House.create(house_params)
    if @house.save
      redirect_to @house
    else
      render 'new'
    end
  end

  def edit
    #Gets @house from set_house
  end

  def update
    if @house.update(house_params)
      redirect_to @house
    else
      render 'edit'
    end
  end

  ...

  private

    def set_house
      @house = House.find(params[:id])
    end

    def house_params
      params.require(:house).permit(:some_parameters, house_colorings_attributes: [:id, :color_id])
    end
end

这是我的_form.html.erb片段,用于房屋newedit
<%= form_for @house do |f| %>
  <div id="house_colorings">
    <%= f.fields_for :house_colorings do |c| %>
      <%= render "house_colorings", f: c %>
    <% end %>
  <%= link_to "Add color", add_color_path, remote: true %>
</div>
<% end %>

_house_colorings.html.erb:

<%= f.collection_select :color_id, Color.all, :id, :name, {include_blank: "Select color"} %>

houses_controller中,我已添加:
def add_color
  respond_to do |format|
    format.js
  end
end

add_color.js.erb:

$("#house_colorings").append("<%= escape_javascript render 'house_colorings', f: c %>");

我为我的add_color方法添加了一条路由:

GET "/add_color" => "houses#add_color"

当我点击我的“添加颜色”链接时,屏幕上没有任何反应,但是在我的日志中出现了“500内部服务器错误”。
Started GET "/add_color" for 127.0.0.1 at 2013-10-26 21:11:41 -0700
Processing by HousesController#add_color as JS
  Rendered houses/add_color.js.erb (11.3ms)
Completed 500 Internal Server Error in 14ms

ActionView::Template::Error (undefined local variable or method `f' for #<#<Class:0x007fc317428538>:0x007fc31710d060>):
    1: $("#house_colorings").append("<%= escape_javascript render 'house_colorings', f: c %>");
  app/views/houses/add_color.js.erb:1:in `_app_views_houses_add_color_js_erb__1847085463095078116_70237941180700'

目前,我只有一个字段来为我的房子添加颜色。我想添加一些ajax,并在表单中添加一个链接,在已有的字段后面添加一个新的字段,但我不确定如何做到这一点。
我已经浏览了Railscasts中的“嵌套模型表单”并使用其中的部分内容来达到我现在的状态,但如果可能的话,我想使用Rails提供的“data_remote”帮助程序。我编辑了我的问题并包括了当我点击添加颜色链接时出现的错误日志。我相当确信我需要更改我的add_color.js.erb或我的houses控制器中的add_color操作。
有什么建议吗?
2个回答

3
好的,你有几个选择。
  1. 参考Nested model forms railscasts:第一部分第二部分中的信息。
  2. 使用FormObject模式来更轻松地嵌套表单。该模式在许多地方都有描述,并且也可以在railscasts(需要订阅)中找到。
  3. 使用像Angular.js这样的js框架,在客户端上动态添加新字段。Angular.js也在railscast(需要订阅)中介绍,并且具有非常丰富的文档
更新: 错误提示已经很明显了。您将一个 c 对象作为表单构建器对象发送到局部视图中。似乎您在houses#add_color操作中没有实例化它。

谢谢回复。我已经浏览了"Nested model form" railscasts的内容并使用其中的部分来达到我现在所在的位置,但如果可以的话,我想使用Rails提供的"data_remote"辅助工具。我编辑了我的问题并包含了当我点击我的“添加颜色”链接时出错时的日志。我相当确定我需要更改我的add_house_coloring.js.erb或我的houses控制器中的add_house_coloring操作之一。 - oobie11
@oobie11 看起来最好使用 locals: {f:c} 而不是只用 f:c - Almaron
感谢您帮助我解决这个问题。我尝试在add_color.js.erb_form.html.erb中分别或一起替换f: clocals: {f: c},但日志中仍然出现相同的500错误。您还有其他想法吗? - oobie11
@oobie11 一些睡眠会有很大帮助 - 可以看一下回答中的更新。 - Almaron
谢谢,那很有道理,但我应该如何实例化house_coloring呢?这个表单是用于新房子的,所以它还没有id。所以类似@house.house_colorings.build这样的代码不起作用。 - oobie11
你正在尝试错误的方法。你需要从你的新HouseColoring对象实例化一个formbuilder对象。我不太确定如何做到这一点。所以我会选择在客户端上做一些事情,而不是在服务器上做。 - Almaron

0

谢谢,我看了一下,但是我使用的是Rails 4,所以“Nested Forms 2”有很多已经过时的代码。 - oobie11
所有那些已经过时的代码都有替代方案,所以只需遵循警告并进行重构即可。 - Almaron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接