Rails不会通过carrierwave传递图像

时间:2014-10-30 00:04:39

标签: ruby-on-rails ruby forms carrierwave

我目前有一个上传表单,它接受一个epub文件,使用epubinfo解析它,然后以另一种形式显示,以验证我们提取的信息是否正确。然后,我们从此表单提交此新上传文件。

第一个表单(upload.html.erb)似乎完全符合我的预期,提取我需要的所有信息,包括封面图片,并在编辑/验证表单中正确显示(new.html.erb )。然而,问题在于第二种形式(新)。发布后,它不会保留显示的封面图像,而不保存任何内容,即使此表单中任何其他已更改(或未更改)的数据发布时也是如此。

要注意的是,当上传表单发布时,public / tmp会获取两个文件,即epub和png,并且在发布新表单后,epub tmp会消失并被公开,但是png会保留在公共状态/ tmp中。

Ruby 2.1.1p76 Rails 4.1 CarrierWave 0.10.0

/views/pages/upload.html.erb

      <%= form_for Book.new, :url => new_book_path do |f| %>
    <div class="form-group">
      <%= f.label :book, "Upload an epub" %>
      <%= f.file_field :book, class: "form-control" %>
      <%= f.hidden_field :book_cache %>
    </div>

    <br />

    <div class="form-group">
      <%= f.button "Upload", class: "btn btn-primary", data: {disable_with: "Uploading..."} %>
    </div>
  <% end %>

/app/controllers/books_controller.rb(有点消毒):

class BooksController < ApplicationController
  before_action :redirect_to_book, only: [:index]
  before_action :set_book, only: [:show, :edit, :update, :destroy, :download]
  before_action :is_mod, only: [:edit, :update, :destroy]

    def create
    @books = Book.new(book_params)
    if @books.author.nil? && book_params[:author_name].present?
      @books.author = Author.where(name: book_params[:author_name]).first_or_create
    end
    if @books.series.nil? && book_params[:series_name].present?
      @books.series = Series.where(name: book_params[:series_name]).first_or_create
    end
    if book_params[:is_public].present?
    else
      @books.is_public == true
    end
    if @books.save
      redirect_to book_path(@books), success: "The book was successfully saved!"
    else
      redirect_to new_book_path
    end
  end

  def new
    @authors = Author.all
    @series = Series.all
    @books = Book.new(book_params)
    @books.extract_epub_info
  end

  private
    def set_book
      @books = Book.find(params[:id])
    rescue ActiveRecord::RecordNotFound
      redirect_to "/404"
    end

    def redirect_to_book
      redirect_to book_path(params[:book_id]) if params[:book_id]
    end

    def book_params
      params.require(:book).permit(:book, :cover, :title, :isbn, :summary, :is_public, :series_nbr, :author_id, :author_name, :series_id, :series_name, :tag_list, :book_cache)
    end

    def is_mod
      unless current_mod
        redirect_to book_path, error: "You're not allowed to edit books."
      end
    end

end

/app/uploaders/book_uploader.rb

class BookUploader < CarrierWave::Uploader::Base
  storage :file

  def store_dir
    "uploads/#{mounted_as}"
  end

  def filename
    "#{model.id}.epub"
  end

end

/app/uploaders/cover_uploader.rb

class CoverUploader < CarrierWave::Uploader::Base
  storage :file

  def store_dir
    "uploads/#{mounted_as}"
  end

  def filename
    "#{model.id}.png"
  end

end

/app/models/book.rb

class Book < ActiveRecord::Base
  belongs_to :author
  belongs_to :series
  has_many :downloads
  has_many :flags
  has_many :ratings
  has_many :raters, :through => :ratings, :source => :users

  validates :title, :author_id, presence: true

  attr_accessor :author_name, :series_name

  acts_as_taggable
  scope :public_books, ->{ where(is_public: true) }
  mount_uploader :book, BookUploader
  # validates_presence_of :book
  mount_uploader :cover, CoverUploader
  # validates_presence_of :cover

    searchable do
      text :title
      text :summary
      text :isbn
    integer :is_public
    end

  def epub
    @epub ||= EPUBInfo.get(book.file.path)
  end

  def extract_epub_info

    if epub.creators.first.name.include? ","
      self.author = Author.where(name: epub.creators.first.name).first_or_create
    else
      parts = epub.creators.first.name.split
      first = parts.first
      last = parts[1..-1].join(" ")

      self.author = Author.where(name: "#{last}, #{first}").first_or_create
    end

    self.title = epub.titles.first
    self.summary = epub.description
    self.is_public = true
    self.isbn = epub.identifiers.find{ |i| i.scheme == "ISBN" }.try(:identifier)

    if epub.cover.present?
      self.cover = epub.cover.tempfile
    else
    end
  end

end

编辑表单适当显示封面,但在提交表单时不会发布。 /views/books/new.html.erb:

<%= form_for @books, url: books_path, html: {multipart: true} do |f| %>
  <% if @books.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@books.errors.count, "error") %> prohibited this author from being saved:</h2>
      <ul>
        <% @books.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <br/><br/>

  <div class="alert alert-warning">
    <strong>Please validate that all of this information is correct before saving the book!</strong>
  </div>

  <br/>

  <% if @books.cover.present? %>
    <div align="center">
      <%= image_tag @books.cover %>
    </div>
  <% end %>

  <div class="form-group">
    <%= f.label :title %>
    <%= f.text_field :title, class: "form-control" %>
  </div>

  <div class="form-group">
    <%= f.label :author %>
    <%= f.collection_select(:author_id, @authors.order("name ASC"), :id, :name, {:include_blank => true} ) %>
    OR New Author Name:
    <%= f.text_field :author_name, class: "form-control" %>
  </div>

  <div class="form-group">
    <%= f.label :isbn %>
    <%= f.text_field :isbn, class: "form-control" %>
  </div>

  <div class="form-group">
    <%= f.label :summary %>
    <%= f.text_area :summary, class: "form-control", size: "20x10" %>
  </div>

  <div class="form-group">
    <%= f.label :series_nbr %>
    <%= f.text_field :series_nbr, class: "form-control" %>
  </div>

  <div class="form-group">
    <%= f.label :series %>
    <%= f.collection_select(:series_id, @series.order("name ASC"), :id, :name, {:include_blank => true} ) %>
    OR New Series Name:
    <%= f.text_field :series_name, class: "form-control" %>
  </div>

  <div class="form-group">
    <%= f.label :tag_list %>
    <%= f.text_field :tag_list, class: "form-control" %>
  </div>

  <%= f.hidden_field :book_cache %>

  <div class="form-group">
    <%= f.label :cover, "Upload a cover" %>
    <%= f.file_field :cover, class: "form-control" %>
  </div>

  <br/>

  <div class="form-group">
    <%= f.hidden_field :is_public, :value => "1" %>
    <%= f.submit class: "btn btn-primary", data: { confirm: "Are you sure all of this information is correct?\rYou will not be able to edit it later." } %>
  </div>

<% end %>

编辑路线11/2 @ 9:20ET

的routes.rb

App::Application.routes.draw do
  root "pages#home"

  # All pages
  get "browse" => "books"
  get "browse/new" => "books#newest"
  get "browse/popular" => "books#popular"
  get "browse/random" => "books#random"
  get "faq" => "pages#faq"
  get "empowerment" => "pages#empowerment"
  get "legal" => "pages#legal"
  get "pages/catalog"
  get "search" => "search#search"
  get "search/search"
  get "upload" => "pages#upload"
  get "download" => "pages#download"
  get "dmca" => "pages#dmca"

  # Catalog Routes
  get "catalog" => "catalog#index", defaults: {format: :atom}
  get "catalog/search" => "catalog#search", defaults: {format: :atom}
  %w{ newest popular random author title serie tag }.each do |section|
    get "catalog/#{section}", controller: :catalog, action: section, defaults: {format: :atom}
  end
  get "catalog/author/:id" => "catalog#authored_by", defaults: {format: :atom}
  get "catalog/tag/:tag" => "catalog#tagged", defaults: {format: :atom}

  # Normal Model stuff
  resources :authors
  resources :series
  resources :books do
    collection do
      get "tagged/:tag", action: :tagged, as: :tagged
      post "new", action: :new, as: :new_book
    end
    member do
      get :download
    end
  end
  resources :tags

  # Stuff for Mods and management
  devise_for :mods
  namespace "admin" do
    resources :mods
  end
  devise_scope :mod do
    get "mods" => "devise/sessions#new"
  end

  # Lists for dropdowns
  get "authorlist" => "books#authorlist"
  get "serieslist" => "books#serieslist"
  get "taglist" => "books#taglist"

  # Let's be nice and support old urls.
  get "book/show/id/:id" => "books#show"
  get "serie/:id" => "series#show"
  get "author/:id" => "authors#show"
  get "browse/author/:id" => "authors#show"

end

我不确定还需要什么。我觉得我所缺少的很简单,但是在盯着它看了这么久之后我才停止取得任何进展。我知道封面图片显示在new.html.erb中,因为它显示在表单中的image_tag中,但是在发布后它不会保存参数。

HALP! :(

1 个答案:

答案 0 :(得分:0)

/views/pages/upload.html.erb - 缺少multipart: true

<%= form_for Book.new, html: { multipart: true } do |f| %>

除非您错误地设置了路线/模型,否则我认为您不需要提供url参数。您也应该以其他形式更改此内容。

/app/controllers/books_controller.rb

您完全缺少编辑/更新方法。这是设计的吗?为什么?这就是您在表单中提供url选项的原因吗?这会引起混乱。

您是否查看了book_params的内容以查看是否正确接收了图像数据?如何检查是否已创建实际图像文件?如果他们被创建,他们可能无法访问(检查文件权限)。

进一步编辑:我无法根据您所显示的内容确定事情的路由方式。请同时显示您的路线,并清楚地描述哪些行为会产生不良后果。

即,&#34;我想创建一本新书,但上传的图片并未保存。#34; (意味着它不存在于数据库中,并且磁盘上的任何地方都没有实际图像。)

&#34;我可以创建一本书并保存图像,但在查看编辑页面时,图像不会显示&#34;