有没有办法在ROR表单中创建未指定数量的嵌套资源?

时间:2018-01-24 02:17:21

标签: ruby-on-rails ruby nested-attributes

我有一个用于创建锻炼程序的表单,它还可以将锻炼创建为锻炼程序的嵌套属性。我准备创建10个练习。但是,如果用户未填写所有10个字段,则会为剩余的练习创建空白数据。有没有办法让ROR表单创建任意数量的嵌套资源而不创建任何空白数据?请注意,解决方案必须只使用ruby / rails而不是javascript。以下是表单中的代码:

<%= f.label :exercise %><br />
<%= f.collection_select :exercise_ids, Exercise.all, :id, :name %>
<%= f.fields_for :exercises, workout_routine.exercises do |exercises_form| %>
  <li>
    <%= exercises_form.label :name %>
    <%= exercises_form.text_field :name %>

    <%= exercises_form.label :sets %>
    <%= exercises_form.text_field :sets %>

    <%= exercises_form.label :reps %>
    <%= exercises_form.text_field :reps %>

    <%= exercises_form.label :target %>
    <%= exercises_form.text_field :target %>
  </li> 
<% end %>

以下是控制器操作的代码:

def new
  @workout_routine = WorkoutRoutine.new 
  @workout_routine.exercises.build 
  @workout_routine.exercises.build
  @workout_routine.exercises.build
  @workout_routine.exercises.build
  @workout_routine.exercises.build
  @workout_routine.exercises.build
  @workout_routine.exercises.build
  @workout_routine.exercises.build
  @workout_routine.exercises.build
  @workout_routine.exercises.build
end




def create
  @workout_routine = WorkoutRoutine.create(workout_routine_params)
  if @workout_routine.save
    redirect_to workout_routine_path(@workout_routine)
  else
    flash[:notice] = "Workout Routine cannot have the same name as an existing routine"
    render :new
  end
end 

以下是添加嵌套属性的自定义编写器方法,位于workout_routine.rb中:

def exercises_attributes=(exercise_attributes)
  exercise_attributes.values.each do |exercise_attribute|
    exercise = Exercise.find_or_create_by(exercise_attribute)
    self.exercises << exercise
  end
end

1 个答案:

答案 0 :(得分:1)

是的,有一种方法可以只使用Rails。在WorkoutRoutine模型中,您需要拒绝空白的练习,如下所示:

# models/workout_routine.rb

class WorkoutRoutine < ApplicationRecord
  has_many :exercises
  accepts_nested_attributes_for :exercises, reject_if: lambda { |attributes| attributes[:name].blank? }
end

此外,您可以将#new动作中的10行相同代码替换为:

10.times { @workout_routine.exercises.build }