1

ファイルを処理するためにActive Storageで動的コクーンフォームを使用してモデルにいくつかのイメージを保存します。Rails 5.2 Cocoonフォームを使用したアクティブストレージ

私は、多くのリンゴを持つ農家クラスを持っています。農家は、農家のフォームを通じてさまざまな種類のリンゴそれぞれに複数の画像を追加できます。ファーマーコントローラ内部の

class Farmer < ActiveRecord::Base 
    has_many :apples, inverse_of: :farmer 
    accepts_nested_attributes_for :apples, allow_destroy: true, 
           reject_if: :all_blank 
end 

class Apple < ActiveRecord::Base 
    has_many_attached :apple_images 
end 

私が持っている:

class Farmer < ApplicationController 


    def update 
    @farmer = Farmer.find(params[:farmer_id]) 

    if @farmer.valid? 
     @farmer.update!(farmer_params) 
     redirect_to edit_farmer_path(farmer_id: @farmer.id) 
    else 
     ... 
     ... 
    end 
    end 

    private 
    def farmer_params 
    params.require(:farmer).permit(
     :farmer_name, 
     apples_attributes: [ 
     :id, 
     :color, 
     :size, 
     :_destroy 
     ]) 
    end 
end 

私の見解私はちょうど今、繭は一度accepts_nested_attributes_forコールを使用してリンゴの属性を保存します私の繭フィールド

<div class="form-field"> 
    <%= f.label :apple_images, "Please upload apple images" %> 
    <%= f.file_field :apple_images, multiple: true, data: { validates: {required: {}} } %> 
</div> 

にこれを追加農家のオブジェクトが保存されます。これはフォームにapple_imagesを追加しようとするまでうまくいきます。

アクティブストレージのreadmeを読むアイテムが保存された直後にファイルを添付することを推奨します。

あなたが読むことができますが、コントローラで単一の画像をしたい場合はreadme here

が、要するに、この操作を行います。

def create 
    message = Message.create! params.require(:message).permit(:title, :content) 
    message.images.attach(params[:message][:images]) 
    redirect_to message 
end 

これを:

#inside an update method 
Current.user.avatar.attach(params.require(:avatar)) 

かを、あなたは複数の画像をしたい場合イメージがコントローラに保存されているモデルの上に直接置かれているとかなり簡単です。まず

、私はそれはそうのようなのparamsにapple_imagesを追加することと同じくらい簡単かもしれ考えた:

def farmer_params 
    params.require(:farmer).permit(
     :farmer_name, 
     apples_attributes: [ 
     :id, 
     :color, 
     :size, 
     :apple_images, 
     :_destroy 
     ]) 
    end 

が、これはエラーを返します:

ActiveModel::UnknownAttributeError - unknown attribute 'apple_images' for Apple.: 

私が使用して考えていますリンゴオブジェクトが更新/作成された後に画像を添付するリンゴモデルのafter_saveコールバック。私はこれを達成する方法もわかりませんが。

<ActionController::Parameters {"utf8"=>"✓", "_method"=>"patch", 
    "farmer"=>{"farmer_name"=>"billy the farmer", "apples_attributes"=> 
    {"0"=>{"color"=>"Green", 
      "size"=>"A", 
      "apple_images"=>[#<ActionDispatch::Http::UploadedFile:0x007f9e8aa93168 @tempfile=#<Tempfile:/var/folders/n7/65r5561n44q0w4bdnmw42l880000gn/T/RackMultipart20171211-87415-1m2w7gh.png>, @original_filename="Screen Shot 2017-12-07 at 09.13.28.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"farmer[apples_attributes][0][apple_images][]\"; filename=\"Screen Shot 2017-12-07 at 09.13.28.png\"\r\nContent-Type: image/png\r\n">, 
          #<ActionDispatch::Http::UploadedFile:0x007f9e8aa93118 @tempfile=#<Tempfile:/var/folders/n7/65r5561n44q0w4bdnmw42l880000gn/T/RackMultipart20171211-87415-1gdbax2.jpeg>, @original_filename="WhatsApp Image 2017-12-06 at 1.23.35 PM.jpeg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"farmer[apples_attributes][0][apple_images][]\"; filename=\"WhatsApp Image 2017-12-06 at 1.23.35 PM.jpeg\"\r\nContent-Type: image/jpeg\r\n">], 
     "_destroy"=>"false", "id"=>"4"}}}, 
    "commit"=>"Next", 
    "controller"=>"farmer/produce", 
    "action"=>"update", 
    "farmer_id"=>"3"} permitted: false> 
+0

あなたのログに一見があり、実際に何が起こっているのかを確認してください。質問を編集してそこに追加してください。 –

+1

こんにちは@TarynEast私はparamsを追加しました。農家 'accepts_nested_attributes_for'によって保存されるリンゴの残りの部分と共に' apple image'が動くことに気付くでしょう。 ActiveStorageは、オブジェクトにアタッチされた画像を投稿したいと思っています。ActiveStorageは多態性テーブルを設定します。リンゴの属性の外でAppleクラスにリンゴの画像を渡すことができたら、画像を添付するためにafter_saveコールバックを設定できるかどうか、私は疑問に思っていましたか? – TheLegend

答えて

3

あなたがすべき:少し失われたと感じ

、任意のアイデアや提案を大幅に

EDIT

これはのparamsは、更新時にどのように見えるかでは理解されるであろうからapple_imagesを削除します(既知の属性ではないため、Apple)。しかし、それを削除すると、画像は保存されません。しかし、これはどのように動作するように意図されていますか(ちょっと変わったイホ)。あなたがドキュメントをチェックした場合

彼らは明示的images属性を無視して、個別に設定します。

message = Message.create! params.require(:message).permit(:title, :content) 
message.images.attach(params[:message][:images]) 

私はあなたがネストされたフォームの設定でこれを解決する方法を全くわかりません。あなたはparams内のすべてのリンゴを繰り返し処理し、apple_imagesを設定しようとしましたが、非常にエラーが起きやすいようです(idを付けないで新しいappleを保存する方法は?)。

あなたは次のようにメソッドを追加してみてください(と許可のparamsでapple_imagesを維持する)ことができます:

def apple_images=(images) 
    self.apple_images.attach(images) 
end 

しかしappleが保存される前に、それが動作するかどうかわかりません。

+1

ありがとう@nathanvda、私は繭から別のステップに画像をアップロードして、オブジェクトに直接追加できるようにしました。私たちが発見したことは、ActiveStorageが画像を保存するために何らかの匿名多態性テーブルを使用していることです。オブジェクトのインスタンスを保存してIDにアクセスできるようにする必要があります。そのため、after_saveコールバックでモデル。私はこの作業を見ることができる唯一の方法は、Cocoonがオブジェクトにアクセスして受け入れられたネストされた属性の属性を渡してから、モデルレベルのコールバックを定義する何らかの方法がある場合です。もう一度ありがとう! – TheLegend

+0

非常に妥当な音です。私は率直に言って同じことをしています:既存のアイテムに添付ファイルを追加するだけです(私はdropzonejsの大ファンです)。 – nathanvda

関連する問題