Accept nested attributes for documents on proposals. Adapt documentable js file to allow many input files at the same page.

This commit is contained in:
Senén Rodero Rodríguez
2017-08-12 17:28:03 +02:00
parent e327b420ff
commit e9c5f77368
10 changed files with 74 additions and 24 deletions

View File

@@ -4,10 +4,14 @@ App.Documentable =
$('input.document_ajax_attachment[type=file]').fileupload $('input.document_ajax_attachment[type=file]').fileupload
paramName : "document[attachment]"
formData: null
add: (e, data) -> add: (e, data) ->
wrapper = $(e.target).parent() wrapper = $(e.target).parent()
$(wrapper).find('.progress-bar-placeholder').empty() $(wrapper).find('.progress-bar-placeholder').empty()
data.progressBar = $('.progress-bar-placeholder').html('<div class="progress-bar"><div class="loading-bar uploading"></div></div>') data.progressBar = $(wrapper).find('.progress-bar-placeholder').html('<div class="progress-bar"><div class="loading-bar uploading"></div></div>')
data.submit() data.submit()
change: (e, data) -> change: (e, data) ->
@@ -26,7 +30,8 @@ App.Documentable =
if result.status == 200 if result.status == 200
$(data.progressBar).find('.loading-bar').removeClass 'uploading' $(data.progressBar).find('.loading-bar').removeClass 'uploading'
$(data.progressBar).find('.loading-bar').addClass 'complete' $(data.progressBar).find('.loading-bar').addClass 'complete'
$('#document_cached_attachment').val result.attachment inputId = '#' + $(e.target).data('chached-attachment-input-field')
$(inputId).val result.attachment
else else
$(data.progressBar).find('.loading-bar').addClass 'errors' $(data.progressBar).find('.loading-bar').addClass 'errors'
$(data.progressBar).prepend("<span>" + result.msg + "</span>") $(data.progressBar).prepend("<span>" + result.msg + "</span>")

View File

@@ -28,6 +28,7 @@ module CommentableActions
def new def new
@resource = resource_model.new @resource = resource_model.new
prepare_new_resource_documents
set_geozone set_geozone
set_resource_instance set_resource_instance
end end
@@ -58,6 +59,7 @@ module CommentableActions
def update def update
resource.assign_attributes(strong_params) resource.assign_attributes(strong_params)
resource = parse_documents(resource)
if resource.save if resource.save
redirect_to resource, notice: t("flash.actions.update.#{resource_name.underscore}") redirect_to resource, notice: t("flash.actions.update.#{resource_name.underscore}")
else else
@@ -110,4 +112,22 @@ module CommentableActions
nil nil
end end
def prepare_new_resource_documents
if @resource.class == Proposal || @resource.class == Budget::Investment
(0..@resource.class.max_documents_allowed - 1).each do
@resource.documents.build
end
end
end
def parse_documents(resource)
resource.documents.each do |document|
document.user = current_user
end
resource.documents = resource.documents.select{|document| document.valid? }.each do |document|
document.attachment = File.open(document.cached_attachment)
end
resource
end
end end

View File

@@ -4,13 +4,9 @@ class DocumentsController < ApplicationController
before_filter :prepare_new_document, only: :new before_filter :prepare_new_document, only: :new
before_filter :prepare_document_for_creation, only: :create before_filter :prepare_document_for_creation, only: :create
before_filter :validate_upload, only: :upload
load_and_authorize_resource :except => [:upload] load_and_authorize_resource :except => [:upload]
skip_authorization_check :only => [:upload] skip_authorization_check :only => [:upload]
def preload
end
def new def new
end end
@@ -35,13 +31,15 @@ class DocumentsController < ApplicationController
end end
def upload def upload
document = Document.new(documentable: @documentable, attachment: params[:document][:attachment].tempfile, title: "faketitle", user: current_user ) attachment = params[:document][:attachment]
document = Document.new(documentable: @documentable, attachment: attachment.tempfile, title: "faketitle", user: current_user )
# We only are intested in attachment validators. We set some fake data to get attachment errors only # We only are intested in attachment validators. We set some fake data to get attachment errors only
if document.valid? document.valid?
if document.errors[:attachment].empty?
# Move image from tmp to cache # Move image from tmp to cache
msg = { status: 200, attachment: params[:document][:attachment].path } msg = { status: 200, attachment: attachment.tempfile.path }
else else
params[:document][:attachment].tempfile.delete attachment.tempfile.delete
msg = { status: 422, msg: document.errors[:attachment].join(', ') } msg = { status: 422, msg: document.errors[:attachment].join(', ') }
end end
render :json => msg render :json => msg
@@ -50,7 +48,7 @@ class DocumentsController < ApplicationController
private private
def find_documentable def find_documentable
@documentable = params[:documentable_type].constantize.find(params[:documentable_id]) @documentable = params[:documentable_type].constantize.find_or_initialize_by(id: params[:documentable_id])
end end
def prepare_new_document def prepare_new_document
@@ -74,8 +72,4 @@ class DocumentsController < ApplicationController
end end
end end
def validate_upload
if @documentable.present?
end
end
end end

View File

@@ -25,6 +25,7 @@ class ProposalsController < ApplicationController
def create def create
@proposal = Proposal.new(proposal_params.merge(author: current_user)) @proposal = Proposal.new(proposal_params.merge(author: current_user))
@proposal = parse_documents(@proposal)
if @proposal.save if @proposal.save
redirect_to share_proposal_path(@proposal), notice: I18n.t('flash.actions.create.proposal') redirect_to share_proposal_path(@proposal), notice: I18n.t('flash.actions.create.proposal')
@@ -76,7 +77,8 @@ class ProposalsController < ApplicationController
def proposal_params def proposal_params
params.require(:proposal).permit(:title, :question, :summary, :description, :external_url, :video_url, params.require(:proposal).permit(:title, :question, :summary, :description, :external_url, :video_url,
:responsible_name, :tag_list, :terms_of_service, :geozone_id) :responsible_name, :tag_list, :terms_of_service, :geozone_id,
documents_attributes: [:cached_attachment, :title] )
end end
def retired_params def retired_params
@@ -122,4 +124,5 @@ class ProposalsController < ApplicationController
def load_successful_proposals def load_successful_proposals
@proposal_successful_exists = Proposal.successful.exists? @proposal_successful_exists = Proposal.successful.exists?
end end
end end

View File

@@ -1,7 +1,7 @@
module DocumentsHelper module DocumentsHelper
def document_attachment_file_name(document) def document_attachment_file_name(document)
document.attachment.attachment_file_name if document.attachment.exists? document.attachment_file_name if document.attachment.exists?
end end
def errors_on_attachment(document) def errors_on_attachment(document)

View File

@@ -17,8 +17,8 @@ class Document < ActiveRecord::Base
validate :validate_attachment_size, if: -> { attachment.present? } validate :validate_attachment_size, if: -> { attachment.present? }
validates :title, presence: true validates :title, presence: true
validates :user, presence: true validates :user, presence: true
validates :documentable_id, presence: true # validates :documentable_id, presence: true
validates :documentable_type, presence: true # validates :documentable_type, presence: true
def validate_attachment_size def validate_attachment_size
if documentable.present? && if documentable.present? &&

View File

@@ -13,6 +13,7 @@ class Proposal < ActiveRecord::Base
documentable max_documents_allowed: 3, documentable max_documents_allowed: 3,
max_file_size: 3.megabytes, max_file_size: 3.megabytes,
accepted_content_types: [ "application/pdf" ] accepted_content_types: [ "application/pdf" ]
accepts_nested_attributes_for :documents
acts_as_votable acts_as_votable
acts_as_paranoid column: :hidden_at acts_as_paranoid column: :hidden_at

View File

@@ -22,10 +22,8 @@
label: false, label: false,
class: 'document_ajax_attachment show-for-sr', class: 'document_ajax_attachment show-for-sr',
data: { data: {
url: upload_documents_url( url: upload_documents_url(documentable_type: @document.documentable_type, documentable_id: @document.documentable_id),
documentable_type: @document.documentable_type, chached_attachment_input_field: "document_cached_attachment",
documentable_id: @document.documentable_id
),
multiple: false multiple: false
} %> } %>
<%= f.label :attachment, t("documents.form.attachment_label"), class: 'button hollow' %> <%= f.label :attachment, t("documents.form.attachment_label"), class: 'button hollow' %>

View File

@@ -47,6 +47,35 @@
<%= f.text_field :external_url, placeholder: t("proposals.form.proposal_external_url"), label: false %> <%= f.text_field :external_url, placeholder: t("proposals.form.proposal_external_url"), label: false %>
</div> </div>
<div class="small-12 column">
<%= f.label :documents %>
<p class="help-text">Aquí puedes añadir hasta 3 doucmentos en formato PDF </p>
<% @proposal.documents.each_with_index do |document, index| %>
<div>
<%= f.fields_for :documents, document do |document_fields| %>
<%= document_fields.text_field :title %>
<%= document_fields.hidden_field :cached_attachment, value: document.attachment.path %>
<%= document_fields.file_field :attachment,
accept: accepted_content_types_extensions(@proposal),
label: false,
class: 'document_ajax_attachment show-for-sr',
data: {
url: upload_documents_url(
documentable_type: document_fields.object.documentable_type,
documentable_id: document_fields.object.documentable_id
),
chached_attachment_input_field: "proposal_documents_attributes_#{index}_cached_attachment",
multiple: false
} %>
<%= document_fields.label :attachment, t("documents.form.attachment_label"), class: 'button hollow' %>
<div class="progress-bar-placeholder"></div>
<p class="file-name"><%= document_attachment_file_name(document) %></p>
<% end %>
</div>
<hr>
<% end %>
</div>
<div class="small-12 medium-6 column"> <div class="small-12 medium-6 column">
<%= f.label :geozone_id, t("proposals.form.geozone") %> <%= f.label :geozone_id, t("proposals.form.geozone") %>
<%= f.select :geozone_id, geozone_select_options, {include_blank: t("geozones.none"), label: false} %> <%= f.select :geozone_id, geozone_select_options, {include_blank: t("geozones.none"), label: false} %>