lundi 15 janvier 2018

Association not saving using form_for (cocoon gem)

Kind of new to rails so help is greatly appreciated.

I'm working on a rails-based app, with a few associations. A user has a diary, and a diary has many workout contents and many nutritional contents. Workout content class has many exercises, and nutritional content class has many meals. When building instances of the associations in rails console, it works. So I know my schema and classes are good, it's just that the data does not persist when submitted through a form. The issue is, when I fill out the information for workout content and exercises, the data persists. Same as when I enter for nutritional content. But when I enter fields for the meals attributes, the data does not persist.

My models are built as so:

class DiaryEntry < ApplicationRecord
 belongs_to :user
 has_many :workout_contents
 has_many :nutritional_contents
 has_many :exercises, through: :workout_contents
 has_many :meals, through: :nutritional_contents
 accepts_nested_attributes_for :exercises, reject_if: :all_blank, allow_destroy: true
 accepts_nested_attributes_for :meals, reject_if: :all_blank, allow_destroy: true
 accepts_nested_attributes_for :nutritional_contents, reject_if: :all_blank, allow_destroy: true
 accepts_nested_attributes_for :workout_contents, reject_if: :all_blank, allow_destroy: true

end

class WorkoutContent < ApplicationRecord
 belongs_to :diary_entry
 has_many :exercises
 accepts_nested_attributes_for :exercises, reject_if: :all_blank, allow_destroy: true

end

class NutritionalContent < ApplicationRecord
 belongs_to :diary_entry
 has_many :meals
accepts_nested_attributes_for :meals, reject_if: :all_blank, 

allow_destroy: true end

class Meal < ApplicationRecord
 belongs_to :nutritional_content
 validates :calories, :protein, :carbs, :fat, :numericality => { :only_integer => true }

end

class Exercise < ApplicationRecord
 validates :name, :length => { :minimum => 2 }
belongs_to :workout_content

end

Below are my forms:

Main form for new entry:

  <%= form_for @diary_entry, url: user_diary_entries_path(current_user) do |f| %>
   <div id='contents'>
     <%= f.fields_for :workout_contents, @diary_entry.workout_contents.build do |content| %>
  <% end %>
  </div>
  <div class='links'>
    <%= link_to_add_association 'Add Workout', f, :workout_contents, partial: 'workout_content_fields' %>
  </div>
  <h3>Add Nutrition Information to Diary</h3>
    <div id='contents'>
      <%= f.fields_for :workout_contents, @diary_entry.nutritional_contents.build do |content| %>
      <% end %>
    </div>
    <div class='links'>
      <%= link_to_add_association 'Add Meal', f, :nutritional_contents, partial: 'nutritional_content_fields' %>
    </div>
<%= f.submit 'Save Diary Entry' %>

workout content fields partial:

<div class='nested-fields'>
  <%= f.label :workout_name, value: "Workout Name"%>
  <%= f.text_field :workout_name%>
  <%= f.label :workout_type, value: "Workout Type"%>
  <%= f.text_field :workout_type%>
  <%= f.fields_for :exercises do |exercise| %>
  <%= render 'exercise_fields', :f => exercise %>
<% end %>
<div class='links'>
  <%= link_to_remove_association "remove workout", f %>
  <%= link_to_add_association 'Add exercise to workout', f, :exercises %>
</div>

Exercise fields partial:

<div class='nested-fields'>
  <%= f.label :name, value: "Exercise Name"%>
  <%= f.text_field :name%>
  <%= link_to_remove_association "remove exercise", f %>
</div>

nutritional content fields partial:

<div class='nested-fields'>
  <%= f.label :meal_type, value: "Meal Type"%>
  <%= f.select :meal_type, [ 'Breakfast','Lunch','Dinner', 'Snack' ], :prompt => 'Select One' %>
  <%= f.fields_for :meals do |meal| %>
  <%= render 'meal_fields', :f => meal %>
<% end %>
<div class='links'>
  <%= link_to_add_association 'Add nutritional details', f, :meals %>
  <%= link_to_remove_association "remove meal", f %>
</div>

Meals fields partial:

<div class='nested-fields'>
  <%= f.label :calories, value: "Calories"%>
  <%= f.text_field :calories%>
  <%= f.label :protein, value: "Protein"%>
  <%= f.text_field :protein%>
  <%= f.label :carbs, value: "Carbs"%>
  <%= f.text_field :carbs%>
  <%= f.label :fat, value: "Fat"%>
  <%= f.text_field :fat%>
  <%= link_to_remove_association "remove nutrition content", f %>

And lastly, in my DiaryEntiresController I have:

def new
 @diary_entry = DiaryEntry.new
end

def create
 @diary_entry = DiaryEntry.new(diary_params)
 @diary_entry.user_id = current_user.id
 @diary_entry.save
 redirect_to user_diary_entry_path(current_user, @diary_entry)
end

and:

  def diary_params
   params.require(:diary_entry).permit(:notes,
   workout_contents_attributes: [:id, :workout_name, :workout_type, :_destroy, exercises_attributes: [:id, :name, :_destroy]],
  nutritional_contents_attributes: [:id, :_destroy, :meal_type, meals_attributes: [:id, :protein, :carbs, :fat, :_destroy]])
 end

Again, adding workout_contents_attributes, exercises_attributes, nutritional_contents_attributes all work. It is only meals_attributes that is giving me trouble.

Thanks in advance!!

Aucun commentaire:

Enregistrer un commentaire