Рубин на рельсах - activestorage - PullRequest
0 голосов
/ 25 октября 2018

после попытки реализовать поле файла, с помощью которого пользователи могут загружать скриншот с обратной связью со скрепкой, я получил некоторые «ошибки дескриптора».Я также задал вопрос о моей проблеме с скрепкой здесь .

Просматривая комментарии к моему вопросу, это может быть связано с multipart.

НО, поскольку я нея не могу сделать что-то вроде form_for multipart true.Я обрабатываю некоторые js через мою текущую форму и не хочу все это менять, поэтому я сейчас попробовал переключиться с устаревшей скрепки на рельсы активного хранилища.Пока все хорошо.

Моя форма все еще работает и работает нормально, пока я не дошёл до момента написания скриншота в базе данных.

Это пример ответа того, что я сейчас получаюпри отправке отзыва.

Started POST "/feedback" for 127.0.0.1 at 2018-10-25 12:21:13 +0200
Processing by FeedbackController#create as */*
  Parameters: {"name"=>"dunnothename", "message"=>"blablablablablabla", "topic"=>"Bug", "screenshot"=>"C:\\fakepath\\dhdr.jpeg"}
  User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (0.2ms)  BEGIN
  Feedback Create (41.3ms)  INSERT INTO "feedbacks" ("message", "topic", "name", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["message", "blablablablablabla"], ["topic", "Bug"], ["name", "dunnothename"], ["created_at", "2018-10-25 10:21:13.410630"], ["updated_at", "2018-10-25 10:21:13.410630"]]
   (0.6ms)  COMMIT
   (0.2ms)  BEGIN
   (0.2ms)  COMMIT
No template found for FeedbackController#create, rendering head :no_content
Completed 204 No Content in 1268ms (ActiveRecord: 48.1ms)

При попытке добавить параметр скриншота в метод контроллера (@feedback = Feedback.create name: ....., screenshot: params[:screenshot]) я получу следующий ответ:

Started POST "/feedback" for 127.0.0.1 at 2018-10-25 12:31:34 +0200
Processing by FeedbackController#create as */*
  Parameters: {"name"=>"dunnothename", "message"=>"blablablablablabla", "topic"=>"Bug", "screenshot"=>"C:\\fakepath\\dhdr.jpeg"}
  User Load (0.7ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
Completed 500 Internal Server Error in 64ms (ActiveRecord: 11.0ms)



ActiveSupport::MessageVerifier::InvalidSignature - ActiveSupport::MessageVerifier::InvalidSignature:
  app/controllers/feedback_controller.rb:6:in `create'

Feedback.rb

class Feedback < ApplicationRecord
  validates :name, presence: true, length: {minimum: 3}
  validates :message, presence: true, length: {minimum: 5}
  validates :topic, length: {minimum: 3}

  has_one_attached :screenshot
end

_feedback.html.erb

<div id="feedback-message" class="feedback-message" style="color: green;">Feedback sent</div>
<span class="label label-info">Name</span><%= text_field_tag :name, "", class: 'form-control' %>
<span class="label label-info">Topic</span>
<select name="topic" id="topic" class="form-control">
  <option value="Bug">Bug</option>
  <option value="Suggestion">Suggestion</option>
  <option value="Other">Other</option>
</select>
<span class="label label-info">Screenshot</span>
<label class="image-upload form-control">
  <i class="fa fa-cloud-download" id="upload_button"></i>
  <input id="upload_input" type="file" name="feedback[screenshot]"/>
</label>
<span class="label label-info">Message</span> <%= text_area_tag :message, "", class: 'form-control', rows: 3 %>
<hr>
<%= submit_tag 'Submit', id: 'submit-feedback', class: 'btn btn-success center' %>

<script>
    $(document).ready(function () {
        var msg = document.getElementById('feedback-message');
        var submit = $('#submit-feedback');
        submit.click(function () {
            msg.style.display = 'block';
            submit.prop('disabled', true);
            setTimeout(function () {
                submit.prop('disabled', false);
                msg.style.display = 'none';
            }, 5000);
            $.ajax({
                url: '/feedback',
                type: 'POST',
                data: {
                    authenticity_token: $('[name="authenticity_token"]').val(),
                    name: $('#name').val(),
                    message: $('#message').val(),
                    topic: $('#topic').val(),
                    screenshot: $('#upload_input').val(),
                },
            });
        });
    });
    var button = document.getElementById('upload_button');
    var input = document.getElementById('upload_input');

    var span = document.createElement('span');
    span.style.paddingLeft = '20px';
    span.style.color = 'green';
    button.appendChild(span);

    input.style.display = 'none';
    button.style.display = 'initial';
    button.addEventListener('click', function (e) {
        e.preventDefault();
        input.click();
    });
    input.addEventListener('change', function () {
        span.innerText = '' + this.value;
    });
</script>

feedback_controller.rb

class FeedbackController < ApplicationController
  def index;
  end

  def create
    @feedback = Feedback.create name: params[:name], message: params[:message], topic: params[:topic]
    @feedback.screenshot.attach(params[:screenshot])
    authorize @feedback
    if @feedback.save
      #FeedbackMailer.with(user: @user).feedback_sent.deliver_later
    end
  end
end

Обновление:

После попытки реализовать то, что упоминал @NirajЯ получаю следующий ответ:

Started POST "/feedback" for 127.0.0.1 at 2018-10-25 13:06:34 +0200
Processing by FeedbackController#create as */*
  Parameters: {"name"=>"askdalskjdajsdpojapsdo", "message"=>"asdasldkaspdkasüpdkapsod", "topic"=>"Bug", "screenshot"=>"C:\\fakepath\\dhdr.jpeg"}
  User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (0.2ms)  BEGIN
  Feedback Create (1.4ms)  INSERT INTO "feedbacks" ("message", "topic", "name", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["message", "asdasldkaspdkasüpdkapsod"], ["topic", "Bug"], ["name", "askdalskjdajsdpojapsdo"], ["created_at", "2018-10-25 11:06:34.518275"], ["updated_at", "2018-10-25 11:06:34.518275"]]
   (0.9ms)  COMMIT
  ActiveStorage::Attachment Load (0.3ms)  SELECT  "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4  [["record_id", 3], ["record_type", "Feedback"], ["name", "screenshot"], ["LIMIT", 1]]
Completed 500 Internal Server Error in 67ms (ActiveRecord: 9.4ms)


ActiveSupport::MessageVerifier::InvalidSignature - ActiveSupport::MessageVerifier::InvalidSignature:
  app/controllers/feedback_controller.rb:7:in `create'

Update2:

class FeedbackPolicy < ApplicationPolicy
  def index?
    true
  end

  def create?
    user.present?
  end

  def new?
    user.present?
  end

  def update?
    return true if user.present?
  end

  def destroy?
    return true if user.present?
  end

  private

  def feedback
    record
  end
end

1 Ответ

0 голосов
/ 25 октября 2018

Примечание: как обсуждалось в разделе комментариев


Я изменил ваш _feedback.html.erb, чтобы загрузка файла работала.Пожалуйста, попробуйте этот код и дайте мне знать.Убедитесь, что вы перезапустили свой сервер rails.

<div id="feedback-message" class="feedback-message" style="color: green;">Feedback sent</div>
<form>
    <span class="label label-info">Name</span><%= text_field_tag :name, "", class: 'form-control' %>
    <span class="label label-info">Topic</span>
    <select name="topic" id="topic" class="form-control">
        <option value="Bug">Bug</option>
        <option value="Suggestion">Suggestion</option>
        <option value="Other">Other</option>
    </select>
    <span class="label label-info">Screenshot</span>
    <label class="image-upload form-control">
        <i class="fa fa-cloud-download" id="upload_button"></i>
        <input id="upload_input" type="file" name="feedback[screenshot]"/>
    </label>
    <span class="label label-info">Message</span> <%= text_area_tag :message, "", class: 'form-control', rows: 3 %>
    <hr>
    <%= submit_tag 'Submit', id: 'submit-feedback', class: 'btn btn-success center' %>
</form>
<script>
    $(document).ready(function () {
        var submit = $('#submit-feedback');
        submit.on('click', function(e) {
            e.preventDefault();
            var msg = document.getElementById('feedback-message');
            var formData = new FormData();
            formData.append('authenticity_token', $('[name="authenticity_token"]').val());
            formData.append('name', $('#name').val());
            formData.append('message', $('#message').val());
            formData.append('topic', $('#topic').val());
            // Attach file
            formData.append('screenshot', $('#upload_input')[0].files[0]); 

            $.ajax({
                url: '/feedback',
                type: 'POST',
                data: formData,
                contentType: false,
                processData: false, 
                beforeSend: function() {
                    msg.style.display = 'none';
                    submit.prop('disabled', true); 
                },
                success: function(resp) {
                    submit.prop('disabled', false);
                    msg.fadIn().delay(5000).fadeOut();
                },
                error: function() {
                    alert('Something went wrong.')
                }
            })

        });
    });
    var button = document.getElementById('upload_button');
    var input = document.getElementById('upload_input');

    var span = document.createElement('span');
    span.style.paddingLeft = '20px';
    span.style.color = 'green';
    button.appendChild(span);

    input.style.display = 'none';
    button.style.display = 'initial';
    button.addEventListener('click', function (e) {
        e.preventDefault();
        input.click();
    });
    input.addEventListener('change', function () {
        span.innerText = '' + this.value;
    });
</script>
...