【问题标题】:How do I save a form in double nested form?如何以双嵌套形式保存表单?
【发布时间】:2016-12-06 20:10:58
【问题描述】:

我有三个模型:EventWorkoutRound

一个人可以创建一个事件,其中包括锻炼,并通过轮次配置组数和重量。

我目前正在使用cocoon gem 来创建嵌套表单。我可以使用表格并保存事件和锻炼,但是,回合没有被保存。

class Event < ActiveRecord::Base
  has_many :workouts, dependent: :destroy
  has_many :rounds, :through => :workouts
  belongs_to :user
  accepts_nested_attributes_for :workouts, :allow_destroy => true
end

class Workout < ActiveRecord::Base
  belongs_to :event
  has_many :rounds, dependent: :destroy
  accepts_nested_attributes_for :rounds, :allow_destroy => true
end

class Round < ActiveRecord::Base
  belongs_to :workout
  belongs_to :event
end

我目前的路线设置是这样的。

Rails.application.routes.draw do
  devise_for :users
  root 'static_pages#index'
  resources :events do
    resources :workouts do
        resources :rounds
      end
  end

在我的控制器中,这就是我拥有新方法的方式。

  New Method for Event
  def new
    @event = current_user.events.new
  end

  New Method for Workout
  def new
    @workout = Workout.new
  end

  New Method for Round
  def new
    @round = Round.new
  end

我目前在事件的视图文件夹下有表单。在事件视图文件的show.html.erb 下,我也尝试通过

显示回合
<% @workout.rounds.each do |round| %>
  <%= round.weight %>
<% end %>

但我收到了undefined method for rounds。不能在事件视图中显示回合吗?

感谢您的帮助!


编辑 1

这是我的嵌套表单。 在顶部,我有 Event 表单。

<%= simple_form_for @event do |f| %>
  <%= f.input :title %>

      <h3>Work Outs</h3>
      <div id="workouts">
        <%= f.simple_fields_for :workouts do |workout| %>
          <%= render 'workout_fields', f: workout %>
        <% end %>
        <div class="links">
          <%= link_to_add_association 'add workout', f, :workouts %>
        </div>
      </div>

      <div class="field">
        <%= f.label :start_time %><br>
        <%= f.datetime_select :start_time %>
      </div>
      <div class="field">
        <%= f.label :end_time %><br>
        <%= f.datetime_select :end_time %>
      </div>
      <div class="field">
        <%= f.label :description %><br>
        <%= f.text_area :description %>
      </div>
        <div class="actions">
        <%= f.submit "Create new Workout" %>
      </div>
  <% end %>
<% end %>

</form>

然后有一个锻炼表格

<div class="nested-fields">
  <%= f.input :name %>

  <div class="rounds">
    <%= f.simple_fields_for :rounds, :wrapper => 'inline' do |round| %>
      <%= render 'round_fields', f: round %>
    <% end %>
    <div class="links">
        <%= link_to_add_association 'add round', f, :rounds, :render_option => { :wrapper => 'inline' } %>
    </div>
  </div>
  <%= link_to_remove_association "remove workout", f %>
</div>

最后,我有了 Round 的表格

<div class="nested-fields">

    <table class="table round-table">
    <tr>
      <td>
        <% index = 0 %>
        <%= f.simple_fields_for :rounds do |round| %>
            <%= render 'set_fields', {f: round, index: index} %>
            <% index = index + 1 %>
        <% end %>
      </td>
      <td>Previous Weight</td>
      <td><%= f.input_field :weight %></td>
      <td><%= f.input_field :repetition %></td>
      <td><%= link_to_remove_association "remove rounds", f %></td>
    </tr>
  </table>
</div>

我能够在 Rails 控制台上创建回合并保存它们。但是当我在网络上使用表单时,我无法保存它们。


编辑 2

这就是我目前设置event_paramsworkout_params 的方式。

def event_params
  params.fetch(:event, {}).permit(:title, :description, :start_time, :end_time, :workouts_attributes => [:id, :name, :category, :_destroy])
end

然后workout_params

def workout_params
  params.require(:workout).permit(:name, :category, :rounds_attributes => [:id, :weight, :set, :repetition, :_destroy])
end

我很困惑为什么表单会保存事件和锻炼。但 Round 总是返回一个空数组。

【问题讨论】:

  • 您是否在EventsController#show 操作中设置了@workout?
  • 由于 has_many 关联,我认为这没有必要。我应该将锻炼设置为 event.workouts 吗?

标签: ruby-on-rails model-view-controller model controller nested-forms


【解决方案1】:

终于解决了!

我也必须在params 中有一个关联。双嵌套关联。

def event_params
  params.fetch(:event, {}).permit(:title, :description, :start_time, :end_time, :workouts_attributes => [:id, :name, :category, :_destroy])
end

对于我的event_params,我只有:workouts_attributes。我认为在workout_params 中有:rounds_attributes 就可以了。但我也需要在event_params 中有rounds_attributes

像下面这样修复它解决了这个问题。

def event_params
  params.fetch(:event, {}).permit(:title, :description, :start_time, :end_time, :workouts_attributes => [:id, :name, :category, :_destroy, :rounds_attributes => [:id, :weight, :set, :repetition, :_destroy]])
end

【讨论】:

    【解决方案2】:

    您已经在事件模型中拥有rounds 属性(has_many :rounds, :through =&gt; :workouts),为什么不使用它?

    <% @event.rounds.each do |round|
      <%= round.weight %>
    <% end %>
    

    【讨论】:

    • 我没有意识到我可以直接从@event 访问round。谢谢。但似乎我的所有回合都没有被保存,因为回合中没有显示任何数字..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多