Skip to content

Instantly share code, notes, and snippets.

@thenapking
Last active May 18, 2021 09:03
Show Gist options
  • Save thenapking/fff6fadfca555e2c8320f50c701283e4 to your computer and use it in GitHub Desktop.
Save thenapking/fff6fadfca555e2c8320f50c701283e4 to your computer and use it in GitHub Desktop.
Setup a nested form with Cocoon
# Add to gemfile
gem 'cocoon'
# In application.js
//= require cocoon
# For a ticket, with associated ticket_comments
class Ticket < ActiveRecord::Base
has_many :ticket_comments, inverse_of: :ticket_detail
accepts_nested_attributes_for :ticket_comments, allow_destroy: true
validates_associated :ticket_comments
end
class TicketComment < ActiveRecord::Base
belongs_to :ticket_detail, inverse_of: :ticket_comments, touch: true, required: true
paginates_per 50
validates_length_of :name, maximum: 255
validates_presence_of :description
validates_uniqueness_of :message_id, :allow_nil => true, :allow_blank => true
default_scope {order(:created_at)}
end
# In the controller permit the related parameters. You should also look up the comments, either using .includes(:ticket_comments) or a separate query.
class TicketsController < ApplicationController
private
def ticket_params
params.require(:ticket).permit(:location_id, :user_id, :name, ticket_comments_attributes: [:ticket_detail_id, :description, :public, :created_by_id, :updated_by_id, :_destroy, attachments: []]). merge(updated_by_id: current_user.id)
end
end
# If you use a decorator file
class TicketDecorator < Draper::Decorator
delegate_all
decorates_association :ticket_comments
end
# In the view, show the list of comments, then allow the user to add a comment using the cocoon gem:
<div>
<%= render :partial => 'ticket_comments/ticket_comment', collection: @ticket_comments, cache: Proc.new{ |ticket_comment| [current_user.locale, current_user.has_permission?(:yapster_push), ticket_comment, 'tc_panel_line']} %>
<%= f.fields_for :ticket_comments do |tc| %>
<% if tc.object.try(:new_record?) && !tc.object.description.blank? %>
<br />
<%= render partial: 'ticket_comment_fields', locals: {f: tc} %>
<% end %>
<% end %>
<div>
<div class="actions">
<%= f.submit 'Update', wrapper: { class: 'btn btn-primary'} %> <!--Duplicate Submit button for whole form-->
<%= link_to_add_association 'Add Update', f, :ticket_comments, :class => "btn btn-primary" %>
</div>
</div>
</div>
# Create a new parial called _ticket_comment_fields.html.erb. You will pass the form f to this parital
<div class = "nested-fields">
<fieldset>
<div class="media-body">
<p><strong><%= current_user.display_name %></strong> said:</p>
<small class="text-muted"><%= Time.current %></small>
<div>
<%= f.check_box :public, label: 'Publish' if current_user.has_permission? :publish %>
<%= f.text_area :description, hide_label: true %>
</div>
<div class="actions">
<%= link_to_remove_association ' Remove', f, :class => "btn btn-xs btn-danger fa fa-trash-o" %>
</div>
</div>
</fieldset>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment