可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm trying to make a create product page in rails. This includes adding multiple images. I have one model for products one for photos and for users. I'm using the paperclip gem for photo upload. But I have 2 problems.
- My file input is not allowing me to select multiple images
- When I view a product no pictures show because pictures are not being saved to database
P.S. I use HAML and I dont have a photo controller.
Products controller
class ProductsController < ApplicationController
before_filter :current_user, only: [:create, :destory]
before_filter :correct_user, only: :destory
def new
@product = Product.new
@photo = Photo.new
5.times { @product.photos.build }
end
def create
@photo = current_user.photos.build(params[:photo])
@product = current_user.products.build(params[:product])
if @product.save
render "show", :notice => "Sale created!"
else
render "new", :notice => "Somehting went wrong!"
end
end
def show
@product = Product.find(params[:id])
end
create product page
= form_for @product, :html => { :multipart => true } do |f|
- if @product.errors.any?
.error_messages
%h2 Form is invalid
%ul
- for message in @product.errors.full_messages
%li
= message
%p
= f.label :name
= f.text_field :name
%p
= fields_for :photos do |f_i|
=f_i.file_field :image
%p.button
= f.submit
product model
class Product < ActiveRecord::Base
attr_accessible :description, :name, :price, :condition, :ship_method, :ship_price, :quantity, :photo
has_many :photos, dependent: :destroy
accepts_nested_attributes_for :photos
belongs_to :user
photo model
class Photo < ActiveRecord::Base
attr_accessible :product_id
belongs_to :product
has_attached_file :image,
:styles => {
:thumb=> "100x100#",
:small => "300x300>",
:large => "600x600>"
}
end
User Model
class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation, :name
attr_accessor :password
has_many :products, dependent: :destroy
has_many :photos,:through=>:products
show product page
%b seller
= @product.user.name
%br
- @product.photos.each do |photo|
= image_tag photo.image.url
回答1:
Are you using Resque
for background job,if yes then u need to start it using rake resque:work QUEUE='*'
.in rails usually Resque
is used to handle background jobs which involves mailer and picture upload.OR an example below for product.html.erb having partial for photos upload for that product with paperclip configures with Amazon S3.
product.html.erb
<%= render :partial => 'photos' %>
_photos.html.erb for atleast one image mandatory
<% if @product.photos[0].nil? %>
<a href="javascript:void(0);" class="add-photos" >
<img src="/assets/default/product-add-photos.png" alt="Add product photos"/>
</a>
<% end %>
<img src="<%= (@product.product_photos[0].nil? ? "" : @product.photos[0].image.url(:small)) %>" id="photos_1" class="product-photos-src <%=@product.photos[0].nil? ? 'dontdisplay' : ''%> "/>
回答2:
your User model not attached to photos so photos only are belongs to Product model so you need to change your User model to be
class User < ActiveRecord::Base
has_many :products
has_many :photos,:through=>:products
end
then you can fetch User photos through
@photos =current_user.photos
or you can build a photo easily
@photo = current_user.photos.build(params[:photo])
also in your views you need to do instead of
= f.file_field :photo, multiple: 'multiple'
use
= fields_for :photos do |f_i|
=f_i.file_field :image
try it .
these is the simple way for has many through association
class Document < ActiveRecord::Base
has_many :sections
has_many :paragraphs, :through => :sections
end
class Section < ActiveRecord::Base
belongs_to :document
has_many :paragraphs
end
class Paragraph < ActiveRecord::Base
belongs_to :section
end
you can check these guide for more info
http://guides.rubyonrails.org/association_basics.html
also you need to put
accepts_nested_attributes_for :photos
inside your Product model
for a complete tutorial about nested forms you can watch these screen cast
http://railscasts.com/episodes/196-nested-model-form-revised
its not free
you can watch these free screen cast if your not subscribed to railscasts.com
http://railscasts.com/episodes/196-nested-model-form-part-1
http://railscasts.com/episodes/197-nested-model-form-part-2
回答3:
Give this a try:
new product page
= form_for @product, :html => {:multipart => true} do |f|
%p
= f.label :description
= f.text_field :description
= f.fields_for :photo do |fp|
= fp.file_field :image
= fp.check_box :_destroy
= fp.label :_destroy, "Remove Image"
%p.button
= f.submit
products controller
def new
@product = Product.new
@product.photos.build
end
def create
@product = current_user.products.create(params[:product])
# or
# @product = current_user.products.build(params[:product])
# @product.save
end
product model
class Product < ActiveRecord::Base
attr_accessible :description, :name, :photo
accepts_nested_attributes_for :photo, :reject_if => lambda { |p| p[:image].nil? }, :allow_destroy => true
belongs_to :user
has_many :photos, dependent: :destroy
validates :user_id, presence: true
validates :photo, presence: true
end
photo model
class Photo < ActiveRecord::Base
attr_accessible :image
belongs_to :product
validates_attachment :image, presence: true,
content_type: { content_type: ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'] },
size: { less_than: 5.megabytes }
has_attached_file :image, styles: { medium: "320x240>"}
end
回答4:
- If you are using nested form, you dont need to create each object separately. Creating product will create the nested photo.
build
method only creates an object. It doesnt save the object to db. You should call object.save
or use create
method instead of build
in your create action
回答5:
I think the real issue here is that you want to attach multiple photo's on one model through paperclip.
Paperclip can only attach 1 file per model, so I suggest you do this:
1. create model Photo with paperclip migrations + has_attached_file
2. Product has_many :photos
3. (optional) make a function to return all image urls, otherwise just call the method in the view
class Product
def get_pics
photos.collect{|p| p.image.url}
end
end
Also a good thing, you can include meta data like alt texts and stuff in the photo model now!
<% @product.photos.each do |photo| %>
<%= image_tag photo.image.url, :alt => photo.alt_text %>
<% end %>
回答6:
I also encountered same issue. I asked on stackoverflow and finally solved myself and rails cast help.
First thing to change is:
You have to follow this to implement nested attributes in model side and controller end:
http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
Then follow the link below, check my answer to the question it includes rails cast links that you should follow for nested forms:
You will see rails cast 2nd link dynamically separate your each filed field as on its own it fails to separate each set of fields. But there is also lack of identity uniqueness algo accuracy in rails-cast. So I enhanced to make sure the uniqueness of certain set of fields to other.
jquery render partial just one time, for second time it not render again just shows previous one