Rails "TypeError (без неявного преобразования nil в String)" при загрузке изображений с использованием image_tag, activeStorage и "has_many_attached" - PullRequest
1 голос
/ 11 января 2020

Я пытаюсь следовать этому руководству, чтобы загрузить несколько изображений для моей модели: https://www.youtube.com/watch?v=A23zCePXe74

Загрузка и сохранение изображений в базу данных с использованием ActiveStorage, похоже, работает, но когда я go на странице показа изображения не отображаются. Я попытался выполнить эти шаги в приложении rails fre sh, и тогда появились изображения, но когда я пытаюсь выполнить действия в существующем приложении rails, я вижу ошибку TypeError и Internal server в консоли сервера и на странице. загружается без изображений.

Буду признателен за любую помощь или предложение.

Моя модель выглядит как

class Post < ApplicationRecord
  has_many_attached :images
end

Мой контроллер выглядит так:

class PostsController < ApplicationController
  before_action :set_post, only: [:show, :edit, :update, :destroy]

  config.relative_url_root = ""

  # GET /posts
  # GET /posts.json
  def index
    @posts = Post.all
  end

  # GET /posts/1
  # GET /posts/1.json
  def show
  end

  # GET /posts/new
  def new
    @post = Post.new
  end

  # GET /posts/1/edit
  def edit
  end

  # POST /posts
  # POST /posts.json
  def create
    @post = Post.new(post_params)

    respond_to do |format|
      if @post.save
        format.html { redirect_to @post, notice: 'Post was successfully created.' }
        format.json { render :show, status: :created, location: @post }
      else
        format.html { render :new }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /posts/1
  # PATCH/PUT /posts/1.json
  def update
    respond_to do |format|
      if @post.update(post_params)
        format.html { redirect_to @post, notice: 'Post was successfully updated.' }
        format.json { render :show, status: :ok, location: @post }
      else
        format.html { render :edit }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /posts/1
  # DELETE /posts/1.json
  def destroy
    @post.destroy
    respond_to do |format|
      format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_post
      @post = Post.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def post_params
      params.require(:post).permit(:title, :body, images: [])
    end
end

Моя _форма. html .erb выглядит так:

<%= form_with(model: post, local: true) do |form| %>
  <% if post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
        <% post.errors.full_messages.each do |message| %>
          <li><%= message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :title %>
    <%= form.text_field :title %>
  </div>

  <div class="field">
    <%= form.label :body %>
    <%= form.text_area :body %>
  </div>

    <div class="field">
      <%= form.label :images %>
        <%= form.file_field :images, multiple: true %>
    </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

Мое шоу. html .erb выглядит так:

<p id="notice"><%= notice %></p>

<p>
  <strong>Title:</strong>
  <%= @post.title %>
</p>

<p>
  <strong>Body:</strong>
  <%= @post.body %>
</p>

<% (0...@post.images.count).each do |image| %>
  <%= image_tag(@post.images[image]) %>
<% end %>

<%= link_to 'Edit', edit_post_path(@post) %> |
<%= link_to 'Back', posts_path %>

Мой Gemfile выглядит так:

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.2'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.0.rc2'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 3.11'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
gem 'redis'
gem 'braintree'
gem 'bcrypt'
gem 'foreman'
gem 'rails-controller-testing'
gem 'faker'
gem 'pagy'
gem 'figaro'
gem 'gon'
gem 'modernizr-rails'
gem 'stripe-rails'
gem 'paperclip'
# thirdparty authentications
gem 'omniauth-google-oauth2'
gem 'omniauth-facebook'
gem 'omniauth-twitter'
gem 'activerecord-session_store'
# for front end
gem 'react-rails'
gem 'bootstrap'
gem 'sprockets-rails'
gem 'jquery-rails'
# catches test emails
gem 'mailcatcher'
gem 'devise'
# admin panel
gem 'rails_admin'

# active storage variant
gem 'mini_magick', '~> 4.8'

Ошибка, которую я вижу в консоли сервера:

  Parameters: {"content_type"=>"image/jpeg", "disposition"=>"inline; filename=\"Capture.JPG\"; filename*=UTF-8''Capture.JPG", "encoded_key"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhaamM1YlRGNmFtdDNNM0p0ZFhwaE5UTnljekYxWW1kaWFIbHFaUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpUVdsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SWtOaGNIUjFjbVV1U2xCSElqc2dabWxzWlc1aGJXVXFQVlZVUmkwNEp5ZERZWEIwZFhKbExrcFFSd1k3QmxRNkVXTnZiblJsYm5SZmRIbHdaVWtpRDJsdFlXZGxMMnB3WldjR093WlUiLCJleHAiOiIyMDIwLTAxLTExVDA0OjA2OjUwLjc2MFoiLCJwdXIiOiJibG9iX2tleSJ9fQ==--983c22b711b8ba21f15b0f7ce768a3165fe9810a", "filename"=>"Capture"}

TypeError (no implicit conversion of nil into String):

rack (2.1.0) lib/rack/files.rb:25:in `expand_path'
rack (2.1.0) lib/rack/files.rb:25:in `initialize'
activestorage (6.0.2.1) app/controllers/active_storage/disk_controller.rb:45:in `new'
activestorage (6.0.2.1) app/controllers/active_storage/disk_controller.rb:45:in `serve_file'
activestorage (6.0.2.1) app/controllers/active_storage/disk_controller.rb:12:in `show'
actionpack (6.0.2.1) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
actionpack (6.0.2.1) lib/abstract_controller/base.rb:196:in `process_action'
actionpack (6.0.2.1) lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack (6.0.2.1) lib/abstract_controller/callbacks.rb:42:in `block in process_action'
.
.
.
puma (3.12.2) lib/puma/configuration.rb:227:in `call'
puma (3.12.2) lib/puma/server.rb:674:in `handle_request'
puma (3.12.2) lib/puma/server.rb:476:in `process_client'
puma (3.12.2) lib/puma/server.rb:334:in `block in run'
puma (3.12.2) lib/puma/thread_pool.rb:135:in `block in spawn_thread'
Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms | Allocations: 623)

Еще одна странная вещь, которую я вижу, когда я запускаю "rails db":

Rack::File is deprecated, please use Rack::Files instead.
psql (12.1 (Ubuntu 12.1-1.pgdg18.04+1), server 11.5 (Ubuntu 11.5-1.pgdg18.04+1))
Type "help" for help.

1 Ответ

4 голосов
/ 11 января 2020

Я тоже наткнулся на это тоже.

TL; DR использует gem 'rack', '~> 2.0.8' в вашем Gemfile

Кажется, последняя версия стойки использует expand_path на root здесь: https://github.com/rack/rack/commit/8f85307711ca5e7a4729641fda1552890ffa129a#diff -894804c816a11584eb28499cb8bbe396R25

Похоже, что в версии 6.2.0.1 Rails используется Rack::File.new(nil) здесь: https://github.com/rails/rails/commit/feab7031b57040afa2b2f5f78f9251dbad6cbdf8#diff -17640e7129bc730594120c1ac91d7928L45 * 1017 более новая версия Rails (только в Github на данный момент), она не ломается, потому что была изменена. Но в текущей версии он ломается.

Вы можете понизить рейтинг стойки до версии 2.0.8 с gem 'rack', '~> 2.0.8' на данный момент.

РЕДАКТИРОВАТЬ: Я открыл вопрос по Rack здесь: https://github.com/rack/rack/issues/1471

...