Tuesday, March 19, 2013

[Rails] Re: nested forms - how to use before/after destroy callback ?

Finally, after_update callback works as needed, te problem was in the new fields_for generation. The below is the correct and updated version:

#timesheet.rb
class Timesheet < ActiveRecord::Base
  has_many :activities, dependent: :destroy
  has_many :time_entries, through: :activities
  accepts_nested_attributes_for :activities, allow_destroy: true
end

#activity.rb
class Activity < ActiveRecord::Base
  has_many :time_entries, order: :workdate, dependent: :destroy
  accepts_nested_attributes_for :time_entries, allow_destroy: true, reject_if: proc { |a| a[:worktime].blank? }
    validate :one_time_entry_present
private
    def one_time_entry_present
      errors[:base] << "At least one entry should be entered" if time_entries.empty?
    end 
end

#time_entry.rb
class TimeEntry < ActiveRecord::Base
  belongs_to :activity
  validates :worktime, presence: true, inclusion: { in: [0.5, 1] } 
end

Every timesheet is created for 7 days (tile_entries) for one activity in the the same form. To delete I use the technic with jQuery explained at Railscats:
#add_remove_fields.js

function remove_fields(link) {
  $(link).prev("input[type=hidden]").val("1");
  $(link).closest('table').find("tr.entry_header").hide();
  $(link).closest(".fields").hide();
}

function add_fields(link, association_id, content) {
  var new_id = new Date().getTime();
  var regexp = new RegExp(association_id, "g");
  $(link).parent().before(content.replace(regexp, new_id));
}

#application_helper.rb

def link_to_remove_fields(name, f)
    f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)")
  end

 def link_to_add_fields(name, f, association, timesheet)
    new_object = f.object.send(association).klass.new
    id = new_object.object_id    
    timesheet.create_activity_days(new_object)
    
    fields = f.fields_for(association, new_object, child_index: id) do |builder|
      render(association.to_s.singularize + "_fields", f: builder)
    end    
                    

    link_to_function(name, "add_fields(this, \"#{id}\", \"#{escape_javascript(fields)}\")")
  end

#timesheets_controller.rb

def update
    begin
      @timesheet = current_user.timesheets.find(params[:id])          
      if @timesheet.update_attributes(params[:timesheet])
        flash[:success] = 'Timesheet updated sucessfully'
        redirect_to @timesheet
      else
        load_entries
        render 'edit'
      end
    rescue Exception => e
      flash[:error] = e.message
      redirect_to edit_timesheet_path(@timesheet)
    end
    
  end

Hope this helps. 

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe@googlegroups.com.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/SPqrx4OMJIsJ.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home


Real Estate