Подтвердить что ты не робот

Carrierwave, Rails 4 и несколько загрузок

Я ударился головой о стену, пытаясь заставить Carrierwave, Rails 4 и Multiple Uploads работать вместе. Я могу получить загрузку одного файла, прекрасно работающую в этом и многих других проектах.

Это не вложенная ситуация - просто загрузите в одну модель Transcription и хотите создать запись для каждого загруженного документа.

Я не могу найти правильный способ объявить поле "документ", используемое для носителя с поддержкой несущей

mount_uploader :document, DocumentUploader

как массив для определения сильных параметров.

Я попытался использовать белый список: whitelisted[:document] = params[:transcription]['document'],

объявление "документа" в виде массива:

params.require(:transcription).permit(..... ,:document => [])

params.require(:transcription).permit(..... , { document: [] })

Все это похоже на то, что я объявляю массив для вложенной модели, но мне действительно нужны сильные параметры Rails 4, чтобы просто увидеть массив "document", созданный файловым полем:: multiple = > true

т. из журнала: form-data; name=\"transcription[document][]

Кто-нибудь успешно выполнил несколько загрузок в Rails 4 с сильными параметрами? Если бы вы поделились этим вопросом?

Спасибо...

Приветствия,

Билл

4b9b3361

Ответ 1

Это решение для загрузки нескольких изображений с использованием несущей в рельсах 4 с нуля

Чтобы сделать это, выполните следующие действия.

rails new multiple_image_upload_carrierwave

В файле gem

gem 'carrierwave'
bundle install
rails generate uploader Avatar 

Создать post scaffold

rails g scaffold post title:string

Создать post_attachment scaffold

rails g scaffold post_attachment post_id:integer avatar:string

rake db:migrate

В post.rb

class Post < ActiveRecord::Base
   has_many :post_attachments
   accepts_nested_attributes_for :post_attachments
end

В post_attachment.rb

class PostAttachment < ActiveRecord::Base
   mount_uploader :avatar, AvatarUploader
   belongs_to :post
end

В post_controller.rb

def show
   @post_attachments = @post.post_attachments.all
end

def new
   @post = Post.new
   @post_attachment = @post.post_attachments.build
end

def create
   @post = Post.new(post_params)

   respond_to do |format|
     if @post.save
       params[:post_attachments]['avatar'].each do |a|
          @post_attachment = @post.post_attachments.create!(:avatar => a, :post_id => @post.id)
       end
       format.html { redirect_to @post, notice: 'Post was successfully created.' }
     else
       format.html { render action: 'new' }
     end
   end
 end

 def update
   respond_to do |format|
     if @post.update(post_params)
       params[:post_attachments]['avatar'].each do |a|
         @post_attachment = @post.post_attachments.create!(:avatar => a, :post_id => @post.id)
       end
     end
  end

  def destroy
    @post.destroy
    respond_to do |format|
      format.html { redirect_to @post }
      format.json { head :no_content }
    end
  end


 private
   def post_params
      params.require(:post).permit(:title, post_attachments_attributes: [:id, :post_id, :avatar])
   end

В представлениях /posts/ _form.html.erb

<%= form_for(@post, :html => { :multipart => true }) do |f| %>
   <div class="field">
     <%= f.label :title %><br>
     <%= f.text_field :title %>
   </div>

   <%= f.fields_for :post_attachments do |p| %>
     <div class="field">
       <%= p.label :avatar %><br>
       <%= p.file_field :avatar, :multiple => true, name: "post_attachments[avatar][]" %>
     </div>
   <% end %>

   <% if params[:controller] == "post" && params[:action] == "edit" %> 
     <% @post.post_attachments.each do |p| %>
       <%= image_tag p.avatar, :size => "150x150" %>
     <% end %>
   <% end %>

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

В views/posts/show.html.erb

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

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

<% @post_attachments.each do |p| %>
  <%= image_tag p.avatar_url, :size => "150x150" %>
  <%= link_to "Destroy", p, method: :delete %>
<% end %>

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

В rails 3 нет необходимости определять сильные параметры и как вы можете определить атрибут_accessible как в модели, так и в accept_nested_attribute для публикации модели, потому что доступный атрибут устарел в рельсах 4.

Ответ 2

CarrierWave не поддерживает несколько загрузок. Он предназначен для связывания одного файла с одним полем.

Если вам требуется несколько загрузок, вам нужно либо несколько полей (каждый с загрузчиком CarrierWave), либо несколько объектов, каждый из которых имеет одно поле для загрузки CarrierWave.

Атрибут multiple также не поддерживается, поэтому, если вы его используете, он полностью зависит от вас, чтобы правильно присвоить параметры.

Ответ 3

Я бы создал модель под названием Documents с полем, в котором смонтировано

class Documents < ActiveRecord::Base
  belongs_to :transcription

  mount_uploader :doc, DocumentUploader
end

class Transcriptions < ActiveRecord::Base
  has_many :documents
end

И у меня все равно будет пользователь ниже строки в моем контроллере:

params.require(:transcription).permit(..... , { document: [] })

Ответ 4

Лучший способ для этого, с которым я столкнулся, - использовать собственный подход CarrierWave. Если у вас уже есть одна загрузка файла, с использованием собственного подхода требуется несколько минут для загрузки нескольких файлов. https://github.com/carrierwaveuploader/carrierwave#multiple-file-uploads