我有2个型号。产品和产品图像。产品has_many
ProductImages。 ProductImage belongs_to
产品。
在我的新视图中。一切都创造了完美。我可以添加尽可能多的图像。产品和ProductImages仍然存在。
但是在编辑视图中,它不会显示图像。在打击示例中,您可以看到该产品有2个图像。但是它们不会在视图中显示。它显示了下面的内容。如何显示图像以便我可以在此编辑视图中添加或删除它们? 产品表格。产品图片位于底部附近。
<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
答案 0 :(得分:1)
你有两个问题:
file_field
nil
#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(如果您想要测试,请注册并转到个人资料。这是一个虚拟应用程序):
在发送属性方面,您需要做几件事:
#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
参数。