使用 paperclip/active 管理员上传多张图片
Multiple image uploads with paperclip/active admin
您好,我希望能够通过下面的代码为 product
上传多张图片,而不是像罐头一样只上传一张。
我不确定如何管理我的客户请求,因为我在使用 active admin
和 paperclip
方面经验不足
我用谷歌搜索并查看了 Stack Overflow 上的各种帖子,但我还没有找到解决方案。任何建议或帮助都会很棒....
这是product
模型
class Product < ActiveRecord::Base
belongs_to :category
belongs_to :label
has_many :product_items, :dependent => :destroy
extend FriendlyId
friendly_id :title, use: [:slugged, :finders]
validates :title, :description, presence: true
validates :price_usd, :price_eu, numericality: {greater_than_or_equal_to: 0.01}
validates :title, uniqueness: true
has_attached_file :image, styles: { medium: "500x500#", thumb: "100x100#" }
validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/
def self.search(query)
where("title LIKE ? OR description LIKE ?", "%#{query}%", "%#{query}%")
end
end
这是 app/admin/product.rb
ActiveAdmin.register Product do
permit_params :title, :slug, :description, :stock_quantity, :image, :price_usd, :price_eu, :category_id, :label_id
index do
column :title
column :slug
column :category
column :label
column :created_at
column :stock_quantity
column :price_eu, :sortable => :price_eu do |product|
number_to_currency(product.price_eu, :unit => " € " , :precision => 0)
end
column :price_euro, :sortable => :price_usd do |product|
number_to_currency(product.price_usd, :unit => " $ " , :precision => 0)
end
actions
end
form do |f|
f.inputs do
f.input :title
f.input :slug
f.input :description, as: :ckeditor, input_html: { ckeditor: { toolbar: 'Full' } }
f.input :stock_quantity
f.input :image
f.input :price_usd
f.input :price_eu
f.input :category
f.input :label
end
actions
end
end
这里是 products_controller.rb
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
def show
@meta_title = "Samoli #{@product.title}"
@meta_description = @product.description
end
def search
@product = Product.search(params[:query]).order("created_at DESC")
@categories = Category.joins(:products).where(:products => {:id => @product.map{|x| x.id }}).distinct
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(:title, :description, :price_usd, :price_eu, :image, :category_id, :stock_quantity, :label_id, :query, :slug)
end
end
我建议使用 jQuery 文件上传之类的东西来为您处理文件上传。
这样您的控制器仍然一次只能处理一个文件上传,尽管您可以一次上传多个文件,因为每个上传都是通过 Ajax 调用单独处理的。
我尝试过其他替代方法,但是尝试一次 post 将多个文件发送到服务器,您很快 运行 进入服务器超时问题(尤其是在 heroku 上)。
这是一个 gem 您可以连接到 ActiveAdmin
https://github.com/tors/jquery-fileupload-rails
如果您在实施方面需要更多帮助,请告诉我。
更新:(请参阅评论了解上下文)
这里有一些示例代码说明了如何在活动管理中实现代码。我知道它看起来像很多代码,但只要逐步完成它,您就会发现它非常简单。
产品型号:
class Product < ApplicationRecord
has_many :photos
end
照片模特:
class Photo < ApplicationRecord
include ActionView::Helpers
belongs_to :product
has_attached_file :image, :styles => { large: "500x500>",thumb: "100x100>" }
validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
def thumb
link_to(image_tag(image.url(:thumb)), thumb_url)
end
private
def thumb_url
Rails.application.routes.url_helpers.admin_product_photo_path(product, self)
end
end
然后在活动管理员中执行以下操作。
ActiveAdmin 产品:
ActiveAdmin.register Product do
permit_params :title
form do |f|
f.inputs do
f.input :title
end
f.actions
end
index do
column :title
column :images do |product|
product.photos.map do |photo|
link_to (image_tag photo.image.url(:thumb)), [:admin, photo.product, photo]
end.join.html_safe
end
actions
end
show do
attributes_table
panel "Images" do
div class: "js-product_photos" do
product.photos.map do |photo|
link_to (image_tag photo.image.url(:thumb)), [:admin, photo.product, photo]
end.join.html_safe
end
div do
semantic_form_for [:admin, resource, Photo.new], multipart: true do |f|
f.inputs do
f.input :image, as: :file,
input_html: {
class: 'js-photo_upload',
type: "file",
name: "photo[image]",
multiple: true
}
end
end
end
end
end
end
注意表单中定义的 html 选项。这就是 jQuery upload 派生出很多选项的地方。 url 的形式也很重要。
我可以在任何地方添加表格,但我认为它在产品展示页面上效果很好。
ActiveAdmin 照片:
ActiveAdmin.register Photo do
belongs_to :product
permit_params :image
controller do
def create
create! do |format|
format.json { render :json => {thumb: resource.thumb} }
end
end
end
show do
attributes_table do
row :product
row :image do |product|
image_tag product.image.url(:large)
end
end
end
end
最后在 active_admin.js.coffee
#= require active_admin/base
#= require jquery-fileupload/basic
$ ->
$('.js-photo_upload').fileupload dataType: 'json', done: (e, data) ->
$('.js-product_photos').append data.result.thumb
就是这样!这些文件应在您 select 后立即通过 AJAX 调用上传。上传后,图像标签将附加到图像列表中。您一次可以 select 多张图片
这实际上只是触及了基本 jQuery 文件上传器功能的皮毛 - 请在此处阅读更多相关信息。 https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin
仅供参考,我构建的应用程序是 rails 5 应用程序,以下是对本示例很重要的 gems:
gem 'activeadmin', github: 'activeadmin'
gem 'inherited_resources', github: 'activeadmin/inherited_resources'
gem 'devise'
gem 'paperclip', "~> 5.0.0"
gem "jquery-fileupload-rails"
更新:基于进一步的问题
现在您可以上传图片,您可以将它们显示在例如产品展示页面 (show.html.erb
):
<h1><%= @product.title %></h1>
<% @product.photos.each do |photo| %>
<%= image_tag(photo.image.url(:large) %>
<% end %>
您好,我希望能够通过下面的代码为 product
上传多张图片,而不是像罐头一样只上传一张。
我不确定如何管理我的客户请求,因为我在使用 active admin
和 paperclip
我用谷歌搜索并查看了 Stack Overflow 上的各种帖子,但我还没有找到解决方案。任何建议或帮助都会很棒....
这是product
模型
class Product < ActiveRecord::Base
belongs_to :category
belongs_to :label
has_many :product_items, :dependent => :destroy
extend FriendlyId
friendly_id :title, use: [:slugged, :finders]
validates :title, :description, presence: true
validates :price_usd, :price_eu, numericality: {greater_than_or_equal_to: 0.01}
validates :title, uniqueness: true
has_attached_file :image, styles: { medium: "500x500#", thumb: "100x100#" }
validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/
def self.search(query)
where("title LIKE ? OR description LIKE ?", "%#{query}%", "%#{query}%")
end
end
这是 app/admin/product.rb
ActiveAdmin.register Product do
permit_params :title, :slug, :description, :stock_quantity, :image, :price_usd, :price_eu, :category_id, :label_id
index do
column :title
column :slug
column :category
column :label
column :created_at
column :stock_quantity
column :price_eu, :sortable => :price_eu do |product|
number_to_currency(product.price_eu, :unit => " € " , :precision => 0)
end
column :price_euro, :sortable => :price_usd do |product|
number_to_currency(product.price_usd, :unit => " $ " , :precision => 0)
end
actions
end
form do |f|
f.inputs do
f.input :title
f.input :slug
f.input :description, as: :ckeditor, input_html: { ckeditor: { toolbar: 'Full' } }
f.input :stock_quantity
f.input :image
f.input :price_usd
f.input :price_eu
f.input :category
f.input :label
end
actions
end
end
这里是 products_controller.rb
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
def show
@meta_title = "Samoli #{@product.title}"
@meta_description = @product.description
end
def search
@product = Product.search(params[:query]).order("created_at DESC")
@categories = Category.joins(:products).where(:products => {:id => @product.map{|x| x.id }}).distinct
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(:title, :description, :price_usd, :price_eu, :image, :category_id, :stock_quantity, :label_id, :query, :slug)
end
end
我建议使用 jQuery 文件上传之类的东西来为您处理文件上传。
这样您的控制器仍然一次只能处理一个文件上传,尽管您可以一次上传多个文件,因为每个上传都是通过 Ajax 调用单独处理的。
我尝试过其他替代方法,但是尝试一次 post 将多个文件发送到服务器,您很快 运行 进入服务器超时问题(尤其是在 heroku 上)。
这是一个 gem 您可以连接到 ActiveAdmin
https://github.com/tors/jquery-fileupload-rails
如果您在实施方面需要更多帮助,请告诉我。
更新:(请参阅评论了解上下文)
这里有一些示例代码说明了如何在活动管理中实现代码。我知道它看起来像很多代码,但只要逐步完成它,您就会发现它非常简单。
产品型号:
class Product < ApplicationRecord
has_many :photos
end
照片模特:
class Photo < ApplicationRecord
include ActionView::Helpers
belongs_to :product
has_attached_file :image, :styles => { large: "500x500>",thumb: "100x100>" }
validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
def thumb
link_to(image_tag(image.url(:thumb)), thumb_url)
end
private
def thumb_url
Rails.application.routes.url_helpers.admin_product_photo_path(product, self)
end
end
然后在活动管理员中执行以下操作。
ActiveAdmin 产品:
ActiveAdmin.register Product do
permit_params :title
form do |f|
f.inputs do
f.input :title
end
f.actions
end
index do
column :title
column :images do |product|
product.photos.map do |photo|
link_to (image_tag photo.image.url(:thumb)), [:admin, photo.product, photo]
end.join.html_safe
end
actions
end
show do
attributes_table
panel "Images" do
div class: "js-product_photos" do
product.photos.map do |photo|
link_to (image_tag photo.image.url(:thumb)), [:admin, photo.product, photo]
end.join.html_safe
end
div do
semantic_form_for [:admin, resource, Photo.new], multipart: true do |f|
f.inputs do
f.input :image, as: :file,
input_html: {
class: 'js-photo_upload',
type: "file",
name: "photo[image]",
multiple: true
}
end
end
end
end
end
end
注意表单中定义的 html 选项。这就是 jQuery upload 派生出很多选项的地方。 url 的形式也很重要。
我可以在任何地方添加表格,但我认为它在产品展示页面上效果很好。
ActiveAdmin 照片:
ActiveAdmin.register Photo do
belongs_to :product
permit_params :image
controller do
def create
create! do |format|
format.json { render :json => {thumb: resource.thumb} }
end
end
end
show do
attributes_table do
row :product
row :image do |product|
image_tag product.image.url(:large)
end
end
end
end
最后在 active_admin.js.coffee
#= require active_admin/base
#= require jquery-fileupload/basic
$ ->
$('.js-photo_upload').fileupload dataType: 'json', done: (e, data) ->
$('.js-product_photos').append data.result.thumb
就是这样!这些文件应在您 select 后立即通过 AJAX 调用上传。上传后,图像标签将附加到图像列表中。您一次可以 select 多张图片
这实际上只是触及了基本 jQuery 文件上传器功能的皮毛 - 请在此处阅读更多相关信息。 https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin
仅供参考,我构建的应用程序是 rails 5 应用程序,以下是对本示例很重要的 gems:
gem 'activeadmin', github: 'activeadmin'
gem 'inherited_resources', github: 'activeadmin/inherited_resources'
gem 'devise'
gem 'paperclip', "~> 5.0.0"
gem "jquery-fileupload-rails"
更新:基于进一步的问题
现在您可以上传图片,您可以将它们显示在例如产品展示页面 (show.html.erb
):
<h1><%= @product.title %></h1>
<% @product.photos.each do |photo| %>
<%= image_tag(photo.image.url(:large) %>
<% end %>