我目前有一个上传表单,它接受一个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! :(
答案 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;