Я работаю над небольшим проектом в Rails, свободно следуя учебнику Rails. У меня есть Carrierwave, Fog и AWS, прекрасно работающие на производстве для загрузки одного изображения. Я хотел добавить галерею изображений, поэтому я решил, что буду следовать ответам SSR по ссылке: Rails 4 multiple image or file upload using carrierwaveRails Carrierwave Несколько изображений не публикуются
Все, кажется, хорошо работает для моей модели, и тесты даже проходят, но когда я иду создавать или редактировать листинг, загрузчик, похоже, не работает. Он будет висеть в течение нескольких минут без разрешения (даже при небольших размерах файлов), и консоль не читает, что при отправке было отправлено действие (просто читается 200 для последнего GET для самой формы). Кроме соглашений об именах (я использую листинг как модель публикации и listing_gallery вместо post_attachment), этапы были идентичными. Разве Rails 5 ничего не изменил о Carrierwave?
listing.rb
class Listing < ApplicationRecord
VALID_PHONE_REGEX = /(\(*(\d{3})\)|(\d{3}-)|(\d{3}))\s*(\d{3})-*(\d{4})/
VALID_ZIP_REGEX = /\d{5}((-)?\d{4})?/
# One use has many listings
belongs_to :user
# Listing_gallery
has_many :listing_galleries
accepts_nested_attributes_for :listing_galleries
# Descending order from newest to oldest as default
default_scope -> { order(created_at: :desc) }
# Carrier Wave mount uploader for images
mount_uploader :picture, PictureUploader
mount_uploader :image, PictureUploader
# Validation of parameters before accepting listing
validates :user_id, presence: true
validates :description, presence: true
validates :street_address, presence: true
validates :city, presence: true, length: { maximum: 30 }
validates :zip_code, presence: true, length: {minimum: 5, maximum: 10}, format: { with: VALID_ZIP_REGEX }
validates :primary_contact, presence: true, length: {minimum: 10, maximum: 15}, format: { with: VALID_PHONE_REGEX }
end
listings_controller.rb
class ListingsController < ApplicationController
before_action :logged_in_user, only: [:new, :create, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update, :destroy]
def new
@listing = Listing.new
@listing_gallery = @listing.listing_galleries.build
end
def create
if current_user.admin?
@listing = current_user.listings.build(listing_params)
@listing.listing_status = "active"
respond_to do |format|
[email protected]!
params[:listing_galleries]['image'].each do |image|
@listing_gallery = @listing.listing_galleries.create!(:image => image)
end
flash[:success] = "New Listing created!"
redirect_to root_url
else
render 'new'
end
end
else
flash[:failure] = "You must be an admin to create a listing."
redirect_to root_url
end
end
def show
@listing = Listing.find(params[:id])
@listing_galleries = @listing.listing_galleries.all
end
def edit
if current_user.admin?
@listing = Listing.find(params[:id])
render 'edit'
end
end
def update
if current_user.admin?
@listing = Listing.find(params[:id])
respond_to do |format|
if @listing.update_attributes(listing_params)
if params[:listing_galleries] != []
params[:listing_galleries]['image'].each do |image|
@listing_gallery = @listing.listing_galleries.create!(:image => image)
end
end
flash[:success] = "Listing Updated!"
redirect_to @listing
else
render 'edit'
end
end
end
end
def destroy
if current_user.admin?
@listing.listing_status = "deleted"
if @listing.save!
flash[:success] = "Listing DELETED"
redirect_to request.referrer || root_url
else
flash[:failure] = "Could not remove listing"
redirect_to request.referrer || root_url
end
end
end
private
# Check for necessary paramters
def listing_params
params.require(:listing).permit(:description, :street_address, :city, :state,
:zip_code, :primary_contact, :secondary_contact,
:listing_status, :asking_price, :renobb, :picture,
{ image: [] },
listing_galleries_attributes: [:id, :listing_id, :image, :_destroy])
end
# Ensure only the creator of the listing is destroying it
def correct_user
@listing = current_user.listings.find_by(id: params[:id])
if current_user.admin?
return true
end
redirect_to root_url if @listing.nil?
end
end
объявления/new.html.erb
<% provide(:title, 'Create Listing') %>
<div id="content">
<div id="sectionbanner">
<p class="goldtext">
Create a New Listing
</p>
</div>
<!-- Article -->
<div id="article">
<div class="form">
<%= form_for(@listing, html: { multipart: true}) do |form| %>
<%= render 'shared/error_messages_listings' %>
<%= form.label :street_address %>
<br>
<%= form.text_field :street_address, class: 'form-control' %>
<br>
<%= form.label :city %>
<br>
<%= form.text_field :city, class: 'form-control' %>
<br>
<%= form.label :state %>
<br>
<%= form.text_field :state, class: 'form-control' %>
<br>
<%= form.label :zip_code %>
<br>
<%= form.text_field :zip_code, class: 'form-control' %>
<br>
<%= form.label :primary_contact %>
<br>
<%= form.text_field :primary_contact, class: 'form-control' %>
<br>
<%= form.label :secondary_contact %>
<br>
<%= form.text_field :secondary_contact, class: 'form-control' %>
<br>
<%= form.label :asking_price %>
<br>
<%= form.number_field :asking_price, class: 'form-control' %>
<br>
<%= form.label :description %>
<br>
<%= form.text_area :description, placeholder: "Details of the lot, rules, etc..." %>
<br>
<%= form.label :renobb %>
<br>
<%= form.check_box :renobb %>
<br>
<span class="picture">
<%= form.file_field :picture, accept: 'image/jpeg, image/gif, image/png' %>
</span>
<br>
<%= form.label :image %>
<br>
<%= form.file_field :image, :multiple => true, name: "listing_galleries[image][]" %>
<br>
<%= form.submit "Create Listing", class: "button" %>
<% end %>
</div>
</div>
</div>
listing_gallery.rb
class ListingGallery < ApplicationRecord
belongs_to :listing
mount_uploader :image, PictureUploader
end
listing_galleries_controller.rb
class ListingGalleriesController < ApplicationController
before_action :set_listing_gallery, only: [:show, :edit, :update, :destroy]
# GET /listing_galleries
# GET /listing_galleries.json
def index
@listing_galleries = ListingGallery.all
end
# GET /listing_galleries/1
# GET /listing_galleries/1.json
def show
end
# GET /listing_galleries/new
def new
@listing_gallery = ListingGallery.new
end
# GET /listing_galleries/1/edit
def edit
end
# POST /listing_galleries
# POST /listing_galleries.json
def create
@listing_gallery = ListingGallery.new(listing_gallery_params)
respond_to do |format|
if current_user.admin?
if @listing_gallery.save
format.html { redirect_to @listing_gallery, notice: 'Listing gallery was successfully created.' }
format.json { render :show, status: :created, location: @listing_gallery }
else
format.html { render :new }
format.json { render json: @listing_gallery.errors, status: :unprocessable_entity }
end
end
end
end
# PATCH/PUT /listing_galleries/1
# PATCH/PUT /listing_galleries/1.json
def update
respond_to do |format|
if current_user.admin?
if @listing_gallery.update(listing_gallery_params)
format.html { redirect_to @listing_gallery, notice: 'Listing gallery was successfully updated.' }
format.json { render :show, status: :ok, location: @listing_gallery }
else
format.html { render :edit }
format.json { render json: @listing_gallery.errors, status: :unprocessable_entity }
end
end
end
end
# DELETE /listing_galleries/1
# DELETE /listing_galleries/1.json
def destroy
if current_user.admin?
@listing_gallery.destroy
respond_to do |format|
format.html { redirect_to listing_galleries_url, notice: 'Listing gallery was successfully destroyed.' }
format.json { head :no_content }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_listing_gallery
@listing_gallery = ListingGallery.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def listing_gallery_params
params.require(:listing_gallery).permit(:listing_id, :image, { image: [] }, :_destroy)
end
end
EDIT Больше файлов из контроллеров и представлений. (Выравнивание может быть забавным на SO, но это хорошо в проекте.)
Спасибо за острый глаз. Это не помогло, но я уверен, что это привело бы к новым проблемам в будущем. –