图像未显示在编辑 - 回形针

时间:2016-02-02 09:53:26

标签: ruby-on-rails ruby-on-rails-4

我有2个型号。产品和产品图像。产品has_many ProductImages。 ProductImage belongs_to产品。

在我的新视图中。一切都创造了完美。我可以添加尽可能多的图像。产品和ProductImages仍然存在。

但是在编辑视图中,它不会显示图像。在打击示例中,您可以看到该产品有2个图像。但是它们不会在视图中显示。它显示了下面的内容。如何显示图像以便我可以在此编辑视图中添加或删除它们? enter image description here 产品表格。产品图片位于底部附近。

<div class="container">
  <div class=“row”>
    <div class="col-md-6 col-md-offset-3">
      <div class="panel panel-primary">
        <div class="panel-body">
          <%= simple_nested_form_for product, html: { class: :js_product_form, id: "js_root_category_#{root_category.id}" } do |f| %>
            <h3><%= root_category.name %></h3>

            <%= f.collection_select :category_id, children_categories_allowed_for(root_category, product),
              :id, :name, include_blank: true, prompt: "Select One Category" %>
​
            <%= f.simple_fields_for :product_sizes do |psf| %>
              <% ps = psf.object %>
        ​
              <%= psf.input :quantity, label: "Quantity for size #{ps.size} for category #{ps.size.category}",
                wrapper_html: { 'data-size_category_id' => ps.size.category_id } %>
              <%= psf.hidden_field :size_id, value: ps.size_id %>
            <% end %>

            <hr>
            <%= f.input :title, label:"Title"%>
            <%= f.input :price, label:"Price"%>
            <%= f.input :description,label:"Description" %>
            <%= f.input :size_description, label:"Size Details"%>
            <%= f.input :shipping_description, label:"Shipping Details"%>
            <%= f.input :tag_list,label:"Tags - Seperate tags using comma ','. 5 tags allowed per product" %>

            <p><%= f.link_to_add "Add a image", :product_images, :data => { :product_image => "#product_images" } %></p>

            <%= f.fields_for :product_images do |product_image| %>
              <% if product_image.object.new_record? %>
                <%= product_image.file_field(:product_image) %>
                <%= product_image.link_to_remove "Remove Image", data: { confirm: "Are you sure you want to delete this image?" } %>
              <% else %>
                <%= product_image.hidden_field :_destroy %>
              <% end %>
            <% end %>
​
            <%= f.button :submit, "Create new product", class: "btn-lg btn-success" %>

          <% end %>
        </div>
      </div>
    </div>
  </div>
</div>
​

产品控制器

class ProductsController < ApplicationController
  before_action :authenticate_user!, only: [:new, :edit, :update, :destroy, :create]
  before_action :set_product, only: [:edit, :show, :update]
  before_action :correct_user_edit, only: [:edit, :update, :destroy]

  def index
    @products = Product.all
  end

  def new
    @product = Product.new
    @root_categories = Category.where(ancestry: nil).preload(:sizes).order(:name)
    @product.product_images.build

    @root_categories.each do |root_category|
      root_category.children.each do |category|
        category.sizes.each do |size|
          @product.product_sizes.build(size_id: size.id, quantity: 0)
        end
      end
    end
  end

  def edit
    category = @product.category         # T-Shirt
    @root_categories = [category.parent] # Men

    category.sizes.each do |size|
      @product.product_sizes.detect do |ps|
        ps.size_id == size.id
      end || @product.product_sizes.build(size_id: size.id, quantity: 0)
    end

    @product.product_images.build unless @product.product_images.any?
  end

  def show
  end

  def update
    if @product.update(product_params)
       redirect_to @product
       flash[:success] = 'Item was successfully updated.'
    else
      render "edit"
    end
  end

  def create
    @product = Product.new product_params
    @product.user_id = current_user.id
    @root_categories = Category.preload(:sizes).order(:name)

    if @product.save
      redirect_to @product
      flash[:success] = "You have created a new product"
    else
      flash[:danger] = "Your product didn't save #{@product.errors.full_messages}"
      render "new"
    end
  end


  private

  def set_product
    @product = Product.find(params[:id])
  end

  def product_params
     params.require(:product).permit(
      :title,
      :price,
      :description,
      :tag_list,
      :category_id,
      :size_description,
      :shipping_description,
      product_images_attributes: [:product_image, :_destroy, :id],
      product_sizes_attributes: [:size_id, :quantity, :id]
    )
  end

  def correct_user_edit
    if @product = current_user.products.find_by(id: params[:id])
    else
      redirect_to root_path if @product.nil?
    end
  end
end

的Javascript

this.productForm = {
  showRootCategory: function () {
    var $forms  = $('form.js_product_form'),
        $select = $('select#js_root_category')

    if($forms.length > 1) {
      var categoryId = $select.val();
      var $selectedForm = $('form#js_root_category_' + categoryId);
    } else {
      var $selectedForm = $forms;
    }

    $forms.hide();
    $selectedForm.show();
  },

  showCategory: function() {
    var $form   = $('form.js_product_form'),
        $select = $('select#product_category_id'),
        $sizes  = $('[data-size_category_id]');

    $sizes.hide();
    if($select.val()) {
      $('[data-size_category_id=' + $select.val() + ']').show();
    }
  }
};

$(function() {
  productForm.showRootCategory();
  $('select#js_root_category').on('change', productForm.showRootCategory);

  productForm.showCategory();
  $('select#product_category_id').on('change', productForm.showCategory);
});

以下是控制台中的Product和ProductImage

2.1.2 :002 > p = _
 => #<Product id: 2, title: "Shorts", description: "description test", created_at: "2016-02-02 09:39:42", updated_at: "2016-02-02 09:39:42", user_id: 1, category_id: 3, price: #<BigDecimal:7fff230514d0,'0.49E2',9(27)>, size_description: "size test", shipping_description: "shipping test">
2.1.2 :003 > p.product_images
  ProductImage Load (0.2ms)  SELECT "product_images".* FROM "product_images" WHERE "product_images"."product_id" = ?  [["product_id", 2]]
 => #<ActiveRecord::Associations::CollectionProxy [#<ProductImage id: 2, product_id: 2, product_image_file_name: "20090a.jpg", product_image_content_type: "image/jpeg", product_image_file_size: 124938, product_image_updated_at: "2016-02-02 09:39:41">, #<ProductImage id: 3, product_id: 2, product_image_file_name: "David-Marvier-Beauty-Fashion-Photography17.jpg", product_image_content_type: "image/jpeg", product_image_file_size: 375907, product_image_updated_at: "2016-02-02 09:39:41">]>
2.1.2 :004 >

Rich的错误

    30:             <%= f.fields_for :product_images do |product_image| %>
    31:               <% if product_image.object.new_record? %>
    32:                 <%= product_image.file_field(:product_image) %>
    33:                 <%= product_image.link_to_remove "Remove Image", data: { confirm: "Are you sure you want to delete this image?" } %>
    34:               <% else %>
 => 35:               <%= binding.pry %>
    36:                 <%= image_tag product_image.object.attachment.url %>
    37:                 <%= product_image.hidden_field :_destroy %>
    38:               <% end %>
    39:             <% end %>
    40:

[1] pry(#<#<Class:0x007fc6fab8acb8>>)> product_image.object.attachment.url
NoMethodError: undefined method `attachment' for #<ProductImage:0x007fc6f363e6a8>
from /Users/josephkonop/.rvm/gems/ruby-2.1.2/gems/activemodel-4.2.0/lib/active_model/attribute_methods.rb:433:in `method_missing'
[2] pry(#<#<Class:0x007fc6fab8acb8>>)> product_image.object.attachment
NoMethodError: undefined method `attachment' for #<ProductImage:0x007fc6f363e6a8>
from /Users/josephkonop/.rvm/gems/ruby-2.1.2/gems/activemodel-4.2.0/lib/active_model/attribute_methods.rb:433:in `method_missing'
[3] pry(#<#<Class:0x007fc6fab8acb8>>)> product_image.object
=> #<ProductImage:0x007fc6f363e6a8
 id: 1,
 product_id: 1,
 product_image_file_name: "hero.jpg",
 product_image_content_type: "image/jpeg",
 product_image_file_size: 157977,
 product_image_updated_at: Tue, 02 Feb

ProductImage.rb

class ProductImage < ActiveRecord::Base
  belongs_to :product

  has_attached_file :product_image, styles: { large: "600x600", medium: "250x250", thumb:"100x100#"}, keep_old_files: true
  validates_attachment_content_type :product_image, content_type: /\Aimage\/.*\Z/
end

1 个答案:

答案 0 :(得分:1)

你有两个问题:

  1. 您无法自动填充file_field
  2. 如果属性传递为nil
  3. ,Paperclip会覆盖您的附件
    #Form
    ...
     <%= f.fields_for :product_images do |product_image| %>
          <% if product_image.object.new_record? %>
              <%= product_image.file_field(:product_image) %>
              <%= product_image.link_to_remove "Remove Image", data: { confirm: "Are you sure you want to delete this image?" } %>
          <% else %>
              <%= image_tag product_image.object.product_image.url %>
              <%= product_image.hidden_field :_destroy %>
          <% end %>
    <% end %>
    

    file_field不会填充现有数据。

    如果您要使用现有图像,则需要显式输出图像(image_tag)。由于您已经在评估object是否为new_record?,因此在else括号中输出图像是有意义的。

    这将“显示”图像。

    我们这样做here(如果您想要测试,请注册并转到个人资料。这是一个虚拟应用程序):

    enter image description here

    在发送属性方面,您需要做几件事:

    #app/models/product.rb
    class Product < ActiveRecord::Base
       has_many :product_images
       accepts_nested_attributes_for :product_images, allow_destroy: true
    end
    
    
    #app/models/product_image.rb
    class ProductImage < ActiveRecord::Base
       belongs_to :product
       has_attached_file :product_image, keep_old_files: true
    end
    

    keep_old_files会保留Paperclip可能会覆盖的所有文件。问题是,由于file_field不会自动填充任何数据,Paperclip会将空集解释为“删除”图像。

    我忘了这是否是 解决方案(还有其他人),但它就是这样的。简而言之,您希望Paperclip忽略空的update参数。