2014-04-19 1 views
0

У меня возникли проблемы при попытке использовать файл с несколькими загрузками.Я не могу загрузить несколько изображений с помощью CarrierWave и Ruby on Rails

это моя форма частичный вид:

<%= simple_form_for @product, :html => { :multipart => true, :class => 'form-horizontal'} do |f| %> 
    <%= f.input :name %> 
    <%= f.input :description %> 
    <%= f.input :price %> 
    <%= f.input :isenable, check_box_html: { class: 'check_box' } %> 
    <div class="row-fluid"> 
    <ul class="thumbnails"> 
     <%= f.simple_fields_for :attachments do |attachments_form| %> 
     <li class="span4"> 
      <div class="thumbnail"> 
       <%= image_tag attachments_form.object.image_url(:thumb).to_s if attachments_form.object %> 
       <%= attachments_form.label :_destroy, "Borrar Imagen" %> 
       <%= attachments_form.file_field :image %> 
      </div> 
     </li> 
     <% end %> 
    </ul> 
    </div> 
    <%= f.button :submit %> 
    <%= link_to t('.cancel', :default => t("helpers.links.cancel")), 
       products_path, :class => 'btn' %> 

<% end %> 

Это мой контроллер:

class ProductsController < ApplicationController 
    before_action :set_product, only: [:show, :edit, :update, :destroy] 


    # GET /products 
    # GET /products.json 
    def index 
    @products = Product.all 
    end 

    # GET /products/list 
    # GET /products/list.json 
    def list 
    @products = Product.all 
    end 

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

    # GET /products/new 
    def new 
    @product = Product.new 
    3.times do 
     attachments = @product.attachments.build 
    end 
    end 

    # GET /products/1/edit 
    def edit 
    end 

    # POST /products 
    # POST /products.json 
    def create 
    @product = Product.new(product_params) 

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

    # PATCH/PUT /products/1 
    # PATCH/PUT /products/1.json 
    def update 
    respond_to do |format| 
     if @product.update(product_params) 
     format.html { redirect_to @product, notice: 'Product was successfully updated.' } 
     format.json { head :no_content } 
     else 
     format.html { render action: 'edit' } 
     format.json { render json: @product.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # DELETE /products/1 
    # DELETE /products/1.json 
    def destroy 
    @product.destroy 
    respond_to do |format| 
     format.html { redirect_to products_url } 
     format.json { head :no_content } 
    end 
    end 

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

    # Never trust parameters from the scary internet, only allow the white list through. 
    def product_params 
     params.require(:product).permit(:name, :description, :price, :isenable, attachments_attributes: [:image, :remove_image]) 
    end 
end 

И это шоу файл:

<%- model_class = Product -%> 
<div class="page-header"> 
    <h1><%=t '.title', :default => model_class.model_name.human.titleize %></h1> 
</div> 

<dl class="dl-horizontal"> 
    <dt><strong><%= model_class.human_attribute_name(:name) %>:</strong></dt> 
    <dd class="lead"><%= @product.name %></dd> 
    <dt><strong><%= model_class.human_attribute_name(:description) %>:</strong></dt> 
    <dd class="lead"><%= @product.description %></dd> 
    <dt><strong><%= model_class.human_attribute_name(:price) %>:</strong></dt> 
    <dd class="lead"><%= @product.price %></dd> 
    <dt><dt> 
</dl> 
<div class="row-fluid"> 
    <ul class="thumbnails"> 
    <% @product.attachments.each do |picture| %> 
     <li class="span4"> 
     <div class="thumbnail"> 
      <%= image_tag picture.image_url(:full).to_s %> 
     </div> 
     </li> 
    <% end %> 
    </ul> 
</div> 
<div class="form-actions"> 
    <%= link_to t('.back', :default => t("helpers.links.back")), 
       products_path, :class => 'btn' %> 
    <%= link_to t('.edit', :default => t("helpers.links.edit")), 
       edit_product_path(@product), :class => 'btn' %> 
    <%= link_to t('.destroy', :default => t("helpers.links.destroy")), 
       product_path(@product), 
       :method => 'delete', 
       :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) }, 
       :class => 'btn btn-danger' %> 
</div> 

Я использую Rails 4.0 .0 ruby ​​2.0.0p247, как я уже сказал, я использую CarrierWave для загрузки файлов, на экране создания, если я оставил изображение пустым, он создает пустую объект изображения. я хочу, чтобы не создавать образ, если пользователь не добавляет файл. Другая проблема, связанная с удалением ссылки. это просто не работает. любое предложение?


Я частично решена проблема, добавив следующую строку в моей модели продукта:

accepts_nested_attributes_for :attachments, :allow_destroy => true, 
         :reject_if => lambda { 
          |a| a['image'].blank? 
         } 

это позволяет мой, чтобы не вставить любое изображение, если это не файл. поэтому часть моей проблемы уже решена, что мне еще нужно решить, так это то, что удаление ссылки не работает.

ответ

1

Хорошо рассмотрев документацию по CarrierWave и в основном документации Rails, я выяснил решение моих проблем. Первый, как я уже говорил ранее решения для предотвращения вставки файлов пустой был включить в моей модели продукции следующую строку:

accepts_nested_attributes_for :attachments, :allow_destroy => true, 
         :reject_if => lambda { 
          |a| a['image'].blank? 
         } 

Чтобы решить эту проблему, CarrierWave не удаляет изображения, я обнаружил, что при использовании вложенная атрибуты должны включать в себя: идентификатор и: _destroy как разрешение на контроллере так:

# permit :id and :_destroy 

    params.require(:author).permit(:name, books_attributes: [:title, :id, :_destroy]) 

Это именно то, что я сделал в моем контроллере, а также я изменил имя флажка в представлении. Так вкратце контроллер было так:

def product_params 
    params.require(:product).permit(:name, :description, :price, :isenable, attachments_attributes: [:image, :_destroy, :id]) 
end 

и вид был таким образом:

<label><%= attachments_form.check_box :_destroy %>Borrar Imagen</lable> 

Делая что я, наконец, решить обе проблемы, все равно спасибо за помощь.

0

В вашем создании действия вы должны создать приложение, вы должны сделать что-то вроде этого ..

@product.attachments.create(:attachment_id).save 

где attachment_id является идентификатором вложений, прикрепленных к изделию.

+0

Извините, но я не могу отказаться от того, как это может решить тот факт, что каждый раз, когда вы редактируете мой продукт, в коллекцию вложений в точности добавляется двойное число объектов (оригинал с изображениями и одинаковое количество пустых объектов, что я думаю, я нужно предотвращать сохранение вложений с нулевым значением в свойстве изображения, но я не могу угадать, как. В любом случае, я попробую то, что вы сказали, и сообщите вам об этом. – Ezequiel

Смежные вопросы