如何在Rails中创建嵌套表单4

我试图通过各自的连接表(exercise_equipment,exercise_muscles)让用户在多对多关系中创建设备和肌肉练习。 我已经得到了每个练习添加一个设备/肌肉的表单,但无法弄清楚如何添加链接以便在动态添加另一个字段到表单。

我已经检查过RailsCasts , 这篇文章 ,已经将它作为我自己以前post的一个侧面问题,但根本无法使这个function起作用。 我是Rails 4的新手,我还在尝试学习Javascript,但是我想深入了解如何设置Rails 4方式!

我的模特:

# id :integer # name :string # is_public :boolean Exercise has_many :exercise_equipment has_many :equipment, :through => :exercise_equipment accepts_nested_attributes_for :exercise_equipment # id :integer # exercise_id :integer # equipment_id :integer # optional :boolean ExerciseEquipment belongs_to :exercise belongs_to :equipment accepts_nested_attributes_for :equipment # id :integer # name :string Equipment has_many :exercise_equipment has_many :exercises, :through => :exercise_equipment 

我的控制器方法:

 def new @exercise = Exercise.new @exercise.exercise_equipment.build @exercise.exercise_muscles.build end def create exercise = current_user.exercises.new( exercise_params ) if exercise.save! redirect_to exercise else render 'new' end end 

意见/运动/ new.html.erb

 

Create New Exercise

意见/运动/ _form.html.erb

 
Public Optional

阿贾克斯

无法弄清楚如何添加链接以在运行中向表单添加另一个字段

这样做的“Rails方式”是从ajax请求中“拉出”一个新的fields_for块实例。

建议使用Ajax的原因是因为它是“Rails方式” – 完全模块化和可扩展:

 #config/routes.rb resources :exercises do get :add_field, on: :collection end #app/models/exercise.rb Class Exercise < ActiveRecord::Base ... def self.build #-> allows you to call a single method exercise = self.new exercise.exercise_equipment.build exercise.exercise_muscles.build return end end #app/controllers/exercises_controller.rb Class ExercisesController < ApplicationController def add_field @exercise = Exercise.build respond_to do |format| format.html format.js end end end #app/views/exercises/new.html.erb <%= form_for @exercise do |f| %> <%= render "fields", locals: { f: f } %> <%= f.submit %> <% end %> #app/views/exercises/add_field.js.erb $("#form_element").append("<%=j render "exercises/form", locals: { exercise: @exercise } %>"); #app/views/exercises/_form.html.erb <%= form_for exercise do |f| %> <%= render "fields", locals: { f: f } %> <% end %> #app/views/exercises/_fields.html.erb <%= f.fields_for :exercise_muscles, child_index: Time.now.to_i do |emf| %> <%= emf.collection_select :muscle_id, Muscle.all, :id, :name, { include_hidden: false } %> <% end %> <%= link_to "New Field", exercises_add_fields_path, remote: :true %> <%= f.fields_for :exercise_equipment, child_index: Time.now.to_i do |eef| %> <%= eef.collection_select :equipment_id, Equipment.all, :id, :name, { include_hidden: false } %> <%= eef.check_box :optional %> Optional <% end %> <%= link_to "New Field", exercises_add_fields_path, remote: :true %> 

这将使您能够通过ajax调用创建字段; 这是正确的方法

在尝试使用Rich的解决方案之后,我想找到一个在使用的代码方面稍微简单一点的解决方案。 我找到了gemCocoon ,效果很好,整合起来非常简单。

我的主要_form视图:

 
<%= f.label :name %>
<%= f.text_field :name, autofocus: true %>
<%= f.check_box :is_public %> Public
<%= f.fields_for :exercise_muscles do |emf| %> <%= render 'exercise_muscle_fields', :f => emf %> <% end %> <%= link_to_add_association 'Add Muscle', f, :exercise_muscles %>
<%= f.fields_for :exercise_equipment do |eef| %> <%= render 'exercise_equipment_fields', :f => eef %> <% end %> <%= link_to_add_association 'Add Equipment', f, :exercise_equipment %>

从这里可以看出,添加一个简单的“link_to_add_association”方法可以处理后台的所有Javascript。 对于未来的读者,以下是每个表单组包含的部分内容:

_exercise_muscle_fields:

<%= f.collection_select :muscle_id, Muscle.all.order( 'muscle_group_id ASC' ), :id, :name, { include_hidden: false } %>

_exercise_equipment_fields:

 <%= f.collection_select :equipment_id, Equipment.all.order( 'name ASC' ), :id, :name, { include_hidden: false } %> <%= f.check_box :optional %> Optional