Гем редактора Trix WYSIWYG от Basecamp не сохраняет прикрепленный файл в приложении Rails 4

Я добавил редактор Trix gem в свое приложение Rails 4 и точно выполнил инструкции на этой странице. Текст отображается правильно после того, как я сохраняю сообщение (полужирный / курсив / зачеркивание / интервал между абзацами все в порядке), НО любые изображения, которые я перетаскиваю в текстовый редактор, исчезают, когда я сохраняю сообщение. Что я делаю неправильно?

Спасибо.

app / assets / stylesheets / application.scss:

/*
    *= require_self
    *= require trix 
*/

@import "bootstrap";
@import "bootstrap-sprockets";
@import "font-awesome"; 
@import url(https://fonts.googleapis.com/css?family=Delius+Swash+Caps);
@import url(https://fonts.googleapis.com/css?family=Reenie+Beanie);
@import url(https://fonts.googleapis.com/css?family=Special+Elite);
@import url(https://fonts.googleapis.com/css?family=Londrina+Shadow);

app / assets / javascripts / application.js:

//= require jquery
//= require jquery_ujs
//= require bootstrap-sprockets
//= require bootstrap
//= require trix
//= require_tree .

_form.html.erb:

<%= form_for @article, html: {multipart: true} do |f| %>
  <p>
    <%= f.label :image %>
    <%= f.file_field :image %>
  </p>
  <p>
    <%= f.label :title %>
    <%= f.text_field :title %>
  </p>
  <p>
    <%= f.label :subtitle %>
    <%= f.text_field :subtitle %>
  </p>

  <%= f.label :text %>
  <%= f.trix_editor :text, class: 'trix-content' %>

  <p>
    <%= f.label :tags %>
    <%= f.text_field :tag_list %>
  </p>

  <p>
    <%= f.submit %>
  </p>

<% end %>

new.html.erb

<div class="container"> 
    <div class="jumbotron">
        <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <h1>New article</h1>
                <%= render 'form' %>
                <%= link_to 'Back', articles_path %>
            </div>
        </div>
    </div>
</div>

Gemfile:

gem 'rails', '4.2.2'
gem 'pg'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.1.0'
gem 'jquery-rails'
gem 'bootstrap-sass', '~> 3.3', '>= 3.3.6'
gem 'devise', '~> 3.5', '>= 3.5.6'
gem "font-awesome-rails"
gem 'paperclip', '~> 4.2'
gem 'aws-sdk', '~> 1.66'
gem 'figaro', '~> 1.1', '>= 1.1.1'
gem 'simple_form'
gem 'mail_form'
gem 'acts-as-taggable-on', '~> 3.4'
gem 'fog'
gem 'rmagick', '~> 2.15', '>= 2.15.4'
gem 'carrierwave'
gem "fog-aws"
gem 'trix', '~> 0.9.0'
gem 'jbuilder', '~> 2.0'
gem 'sdoc', '~> 0.4.0', group: :doc

person Noob005    schedule 28.04.2016    source источник
comment
Я слышал, что bootsy-demo.herokuapp.com хороший   -  person Abram    schedule 28.04.2016
comment
Спасибо, Абрам. Я пробовал это с меньшим успехом: / Я не силен во фронтенд-разработке, поэтому я уверен, что упускаю что-то действительно очевидное.   -  person Noob005    schedule 28.04.2016
comment
Вы внимательно прочитали этот раздел? github.com/basecamp/trix#storing-attached-files   -  person Abram    schedule 28.04.2016


Ответы (2)


В этом примере я создал Image модель и контроллер, у которых есть методы GET и POST. Я использовал refile для обработки загрузки файлов, но с carrierwave он работал бы аналогично. Идея состоит в том, чтобы прослушать событие trix-attachment-add и отправить XHR POST на ваш ImagesController. Отсюда вы можете отправить ответ JSON обратно на свой запрос XHR и вызвать JSON.parse, чтобы захватить текст ответа. Trix ожидает, что будет возвращен действительный URL и атрибуты, установленные для вложения. Пока это не будет сделано должным образом, он будет в состоянии ожидания и фактически не будет сохранять изображение и / или подпись.

  # ImagesController
  def create
    @image = Image.new(image_params)
    @image.save

    respond_to do |format|
      format.json { render :json => { url: Refile.attachment_url(@image, :image)} }
    end
  end

# Some Javascript

(function() {
  var host, uploadAttachment;

  document.addEventListener("trix-attachment-add", function(event) {
    var attachment;
    attachment = event.attachment;
    if (attachment.file) {
      return uploadAttachment(attachment);
    }
  });

  host = "/images";

  uploadAttachment = function(attachment) {
    var file, form, xhr;
    file = attachment.file;
    form = new FormData;
    form.append("Content-Type", file.type);
    form.append("image[image]", file);
    xhr = new XMLHttpRequest;
    xhr.open("POST", host, true);
    xhr.upload.onprogress = function(event) {
      var progress;
      progress = event.loaded / event.total * 100;
      return attachment.setUploadProgress(progress);
    };
    xhr.onload = function() {
      var href, url;
        url = href = JSON.parse(this.responseText).url;
        return attachment.setAttributes({
          url: url,
          href: href
        });
    };
    return xhr.send(form);
  };


}).call(this);
person kobaltz    schedule 08.05.2016
comment
Куда поставить контроллер изображения? - person Jakxna360; 08.09.2016
comment
@ Jakxna360 контроллер будет принадлежать другим контроллерам в приложении / контроллере - person Quentin Gibson; 26.04.2020

В качестве альтернативы ответу @kobaltz вы можете использовать fetch следующим образом:

uploadAttachment = function(attachment) {
    var file, form, key, xhr;
    file = attachment.file;
    form = new FormData;
    form.append("Content-Type", file.type);
    form.append("image[picture]", file);
    fetch(host, {
      method: "POST",
      body: form,
      headers: {
        'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content'),
        'X-Requested-With': 'XMLHttpRequest'
      },
      credentials: 'same-origin'
    })
    .then(function(response) {
      if (response.ok) {
        return response.json();
      }
    })
    .then(function(json) {
      var href, url;
      url = href = json.url;
      return attachment.setAttributes({
        url: url,
        href: href
      });
    })
  };
person Pietro    schedule 26.09.2017