#ruby-on-rails #vue.js #vuejs2
Вопрос:
У меня есть база данных, полная билетов, каждый с вложениями. В настоящее время каждый билет имеет вложение с изображением, и моя текущая цель-ввести текст (в VueJS), который прикрепит этот текст к билету.
Однако после ввода «Привет, мир» я вижу в своих пулах, что компонент данных принял ввод, т. Е.: «Новое значение: «Привет, мир». Но затем в моей консоли Rails я запускаю запрос
CcVTicket.last.message_attachments
и ничего не изменилось. Я изо всех сил пытаюсь понять, что я здесь не связываю, возможно, у кого-то здесь будет лучшее представление о том, какой путь выбрать для решения этой проблемы. Я прикреплю соответствующие(?) файлы ниже.
Контроллер:
module Panel
class CcVAttachmentsController < CcVEntitiesBaseController
def update
run 'ccenter.cc_v_attachments.update'
end
private
def ticket_model
CcVAttachment.find(params[:id]).ticket
end
end
end
Модель:
class CcVAttachment < CcContext
include Attachable
CONTENT_TYPES = %w[image/jpeg image/jpg image/png image/tiff application/pdf text/plain].freeze
belongs_to :message, class_name: 'CcMessage', foreign_key: :parent_idx
belongs_to :document_type
has_one :ticket, through: :message
has_many :message_attachments, class_name: 'CcVDocument', foreign_key: :parent_id
configure_storage(:cc_v_attachments, name: :content)
validates_attachment :content, content_type: { content_type: CONTENT_TYPES }
end
Обновление.rb
module Ccenter
module Operations
module CcVAttachments
class Update < ApplicationOperation
include Model
model ::CcVAttachment, :update
attr_accessor :deleted_document_ids
contract do
model :cc_v_attachment
property :ignore_attachment
property :document_type_id
property :approved_attachment
end
private
def process_model!
CcVAttachment.transaction do
model.document_type = nil if model.ignore_attachment
delete_associations if model.ignore_attachment || !model.approved_attachment
model.save!
attach_to_single_cf(model)
end
model.reload
end
def attach_to_single_cf(model)
return unless attach_to_single_cf?(model)
Ccenter::Operations::CcVDocuments::Create
.run(cc_v_document: { parent_id: model.id, case_file_id: model.ticket.case_files.first.id })
end
def attach_to_single_cf?(model)
model.ticket.case_files.count == 1 amp;amp; !model.ignore_attachment amp;amp;
model.approved_attachment amp;amp; model.document_type_id
end
def delete_associations
model.documents.map { |doc| doc.destroy.id }
end
end
end
end
end
Create.rb
module Ccenter
module Operations
module CcVDocuments
class Create < ApplicationOperation
include Model
model ::CcVDocument, :create
contract do
model :cc_v_document
property :parent, smart_class: ::CcVAttachment, validates: { presence: true, }
property :case_file, smart_class: ::CcVCaseFile, virtual: true,
validates: {
presence: true,
'ccenter/validators/participant_present' => true,
}
validate :attachment_has_document_type
def attachment_has_document_type
return unless parent
return if parent.document_type_id
errors.add(:base, I18n.t('ccenter.tickets.errors.document_type_missed'))
end
end
delegate :parent, :case_file, to: :contract
private
def process_model!
model.participant_id = case_file.participant_id
model.case_file = case_file.case_file
model.root_id = parent.root_id
model.save!
end
end
end
end
end
Vue.js
<template>
<section class="p-1">
<b-switch
v-model="attachmentAccepted"
:disabled="waiting.updateAttachment"
>
{{attachmentAcceptedLabel}}
</b-switch>
<template v-if="attachmentAccepted">
<b-field
:label="t('document_type')"
>
<b-select
v-model="documentType"
icon="file-alt"
:disabled="waiting.updateAttachment"
>
<optgroup
v-for="group in allDocumentTypeGroups"
:key="group.id"
:label="t(group.name)"
>
<option
v-for="type in group.documentTypes"
:key="type.id"
:value="type.id"
>
{{t(type.name)}}
</option>
</optgroup>
</b-select>
</b-field>
<b-field>
<b-checkbox
v-model="approveAttachment"
:disabled="waiting.updateAttachment"
>
{{ t('tickets.approved') }}
</b-checkbox>
</b-field>
<b-field label="Comments">
<b-input v-model="name"></b-input>
</b-field>
<template v-if="attachmentAccepted amp;amp; documentType amp;amp; approveAttachment">
<label class="label">{{t('case_files')}}</label>
<document-checkbox
v-for="cf in currentTicketCaseFiles"
:key="cf.id"
:case-file="cf"
:attachment="attachment"
/>
</template>
</template>
</section>
</template>
<script>
import { mapGetters, mapMutations } from 'vuex';
import { mapServerActions } from "../../../../../../_frontend_infrastructure/javascript/lib/crudvuex_new";
import DocumentCheckbox from './DocumentCheckbox';
import AttachmentTypeMixin from './mixins/AttachmentTypeMixin';
export default {
name: 'AttachmentEditForm',
mixins: [AttachmentTypeMixin],
components: { DocumentCheckbox },
props: {
attachment: Object,
slideIndex: Number,
},
data() {
return {
waiting: {},
name: "",
}
},
computed: {
...mapGetters(['allDocumentTypeGroups', 'currentTicketCaseFiles', 'activeAttachmentIndex', 'showAttachmentsPreview', 'activeAttachments']),
attachmentAcceptedLabel() {
return this.attachmentAccepted ? this.t('accepted') : this.t('ignored');
},
attachmentAccepted: {
get: function () {
return !this.attachment.ignoreAttachment;
},
set: function (val) {
return this.updateAttachment([this.attachment.id, { ignoreAttachment: !val }]);
},
},
documentType: {
get: function() {
return this.attachment.documentTypeId;
},
set: function(val) {
return this.updateAttachment([this.attachment.id, { documentTypeId: val }]);
},
},
approveAttachment: {
get: function() {
return this.attachment.approvedAttachment;
},
set: function(val) {
return this.updateAttachment([this.attachment.id, { approvedAttachment: val }]);
},
},
},
methods: {
...mapServerActions(['updateAttachment']),
...mapMutations(['changeActiveAttachmentIndex', 'closeAttachmentsPreview']),
processAttachmentPreviewOpen() {
if (this.showAttachmentsPreview amp;amp; this.slideIndex === this.activeAttachmentIndex) {
if (this.isImage(this.attachment) amp;amp; !this.approveAttachment) {
this.approveAttachment = true;
return;
}
}
}
},
watch: {
activeAttachmentIndex() {
this.processAttachmentPreviewOpen();
},
'attachment.documents.length'(value) {
let isAttachmentFullyProcessed =
this.attachmentAccepted amp;amp; this.documentType amp;amp; this.approveAttachment amp;amp; value > 0;
if (isAttachmentFullyProcessed amp;amp; this.currentTicketCaseFiles.length === 1) {
let maxPossibleIndex = (this.activeAttachments.length - 1);
if (this.activeAttachmentIndex < maxPossibleIndex) {
setTimeout(() => this.changeActiveAttachmentIndex(this.activeAttachmentIndex 1), 500);
} else {
this.$buefy.toast.open({
message: 'All attachments were processed!',
type: 'is-success'
});
setTimeout(() => this.closeAttachmentsPreview(), 1000);
}
}
}
},
mounted() {
this.processAttachmentPreviewOpen();
}
};
</script>