link_to_remove_association is not removing?

10.4k views Asked by At

How can we fix the nested_attribute: _result_fields.html.erb so that when a user clicks "Delete" that it actually deletes it? Whereas now clicking it does nothing.

<%= f.text_field :result_value, class: 'form-control', placeholder: 'Enter Result' %>
<%= f.date_select :date_value, :order => [:month, :day, :year], :with_css_classes => true, :class => "date-select" %>
<%= f.check_box :bad %>
<%= link_to_remove_association f do %>
  Delete
<% end %>

stats has_many results

stats/_form

<div id="results">
  <%= f.fields_for :results do |result| %>
  <%= render 'result_fields', :f => result %>
  <% end %>
</div>

  <span class="label label-primary">
    <%= link_to_add_association f, :results do %>
    <span class="glyphicon glyphicon-plus"></span> Result
    <% end %>
  </span>

In stats_controller I have this as a params: results_attributes: [:id, :result_value, :date_value, :bad, :_destroy]

The models:

class Stat < ActiveRecord::Base
  has_many :results
  accepts_nested_attributes_for :results, :reject_if => :all_blank, :allow_destroy => true
end

class Result < ActiveRecord::Base
  belongs_to :stat
end

I'm using the cocoon gem.

Please let me know if you need further code or explanation. Thank you!

BY REQUEST

class StatsController < ApplicationController
  before_action :set_stat, only: [:show, :edit, :update, :destroy, :like]
  before_action :logged_in_user, only: [:create, :destroy]
  before_action :correct_user, only: [:edit, :update, :destroy]

  def index
    if params[:tag]
      @stats = Stat.tagged_with(params[:tag])
    else
      @stats = Stat.joins(:results).all
      @averaged_stats = current_user.stats.averaged
      @instance_stats = current_user.stats.instance
    end
  end

  def show
    @stat = Stat.find(params[:id])
    @commentable = @stat
    @comments = @commentable.comments
    @comment = Comment.new
    @notable = @stat
    @notes = @notable.notes
    @note = Note.new
    @correct_user = current_user.stats.find_by(id: params[:id])
  end

  def new
    @stat = current_user.stats.build 
  end

  def edit
  end

  def create
    @stat = current_user.stats.build(stat_params)
    if (params[:commit] == 'conceal')
      @stat.conceal = true
      @stat.save
      redirect_to @stat, notice: 'Stat was successfully created'
    elsif
      @stat.save
      track_activity @stat
      redirect_to @stat, notice: 'Stat was successfully created'
    else
      flash.now[:danger] = 'Required Fields: "Averaged or Instance", "Enter Action", "Enter Metric", and "+ Result"'
      render 'new'
    end
  end

  def update
    if @stat.update(stat_params)
      redirect_to stats_url, notice: 'Goal was successfully updated'
    else
      render action: 'edit'
  end
end

  def destroy
    @stat.destroy
    @result.destroy
    redirect_to stats_url
  end

  def like
    @stat = Stat.find(params[:id])
    @stat_like = current_user.stat_likes.build(stat: @stat)
    if @stat_like.save
      @stat.increment!(:likes)
      flash[:success] = 'Thanks for liking!'
    else
      flash[:error] = 'Two many likes'
    end  
      redirect_to(:back)
  end

  private
    def set_stat
      @stat = Stat.find(params[:id])
    end

    def correct_user
      @stat = current_user.stats.find_by(id: params[:id])
      redirect_to root_url, notice: "Not authorized to edit this stat" if @stat.nil?
    end

    def stat_params
      params.require(:stat).permit(:categories, :like, :action, :metric, :date, :comment, :private_submit, :tag_list, results_attributes: [:id, :result_value, :date_value, :bad, :_destroy])
    end
end

stat.js

$( document ).ready(function() {
  $('.date-format-switcher').click(function(event){
    event;
    if ($(this).attr('id') == 'stat_categories_instance') {
      $('.day').show();
     } else if ($(this).attr('id') == 'stat_categories_averaged') {
        $('.day').hide();
    }
})
  $('.add-form-padding').on('cocoon:after-insert', function(e, insertedItem) {
    if($('#stat_categories_instance').is(':checked')) {
      $('.day').show();
    } else {
        $('.day').hide();
    }
})
});
2

There are 2 answers

5
nathanvda On BEST ANSWER

If the link_to_add_association works, the javascript is loaded correctly.

Still a bit confused about what is not working. If clicking the link_to_remove_association does not remove anything visibly from the page, you are missing the correct wrapper-class. By default it should be .nested-fields, but this can be overruled by specifying it explicitly (as documented ).

But if the items are visually removed, and you think it should be sent to the server immediately, then you misunderstand how cocoon works: you edit a form, which is only saved (sent to the server) when you submit the form. So the link_to_remove_association only visible removes the nested-child, and edits the contents of the form (sets the _destroy flag), so when saving/submitting the form, the nested child will be deleted.

4
rorra On

Maybe the problem is that you didn't include the javascript that cames with the gem in order to invoke the links as expected, are you using ruby on rails 3 or 4? That's really important when asking questions in rails, since they differ a lot

Check your application.js file that is located in app/assets/application.js and make sure that you added this line:

//= require cocoon

if you already added the assets, check the source code of the page and please confirm that the javascript defined for cocoon is being loaded in the page

if that is already done, please update the question and add the rails log that you see when you click on the link and also let me know which version of rails you are using