ポリモーフィズムを使用して、ネストされた属性をファイルのアップロードで動作させるのに問題があります。これが私のアプリからの関連するsourcecdeです。
app/uploaders/image_uploader.rb
# encoding: utf-8
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
storage :file
version :thumb do
process resize_to_fill: [50, 50]
process convert: 'jpg'
end
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
アプリ/モデル/写真.rb
class Photo < ActiveRecord::Base
attr_accessible :image, :imageable_id, :imageable_type
belongs_to :imageable, polymorphic: true
mount_uploader :image, ImageUploader
validates_presence_of :image, :imageable_id, :imageable_type
end
app/controllers/photos_controller.rb
class PhotosController < InheritedResources::Base
def create
# TODO enforce imageable_id belongs to current account
@photo = Photo.new(params[:photo])
if @photo.save
redirect_to @photo.imageable, notice: 'Photo saved'
else
flash[:error] = 'Photo could not be saved'
redirect_to(:back)
end
end
end
アプリ/モデル/listing.rb
class Listing < ActiveRecord::Base
attr_accessible :photos_attributes
has_many :photos, :as => :imageable, :dependent => :destroy
accepts_nested_attributes_for :photos
mount_uploader :logo, ImageUploader
end
アプリ/ビュー/リスト/show.html.haml
%p
%b Photos:
%ul.inline
- @listing.photos.each do |photo|
%li= link_to(image_tag(photo.image_url(:thumb)), photo.image_url)
= simple_form_for @listing.photos.new do |f|
= f.hidden_field :imageable_id
= f.hidden_field :imageable_type
= f.input :image, as: :file
= f.submit 'Upload'
上記の形式は機能しますが、 :imageable_id と :imageable_type を渡すのは私にはハックのように感じられ、大量割り当てのセキュリティ問題に簡単につながる可能性があります。さらに、これには Photo に attr_accessible があり、photos_controller.rb と :photos への RESTful ルートが必要です。これはすべて非常に間違っているようです。
これは、Rails のように感じた私の元のフォームですが、うまくいきませんでした。ポリモーフィック アソシエーションが何らかの形で干渉しているようです。写真の属性は、別の params[:photo] ではなく、params[:listing] で投稿する必要があると思います。
アプリ/ビュー/リスト/_form.html.haml
= simple_form_for @listing do |f|
= simple_fields_for :photos, @listing.photos.new do |pf|
= pf.input :image, :as => :file
= f.submit 'Upload'
誰かがこれを行う正しい方法を示すことができますか?