Search code examples
ruby-on-railspolymorphismpaperclipnested-attributesstrong-parameters

Paperclip Nested attributes on polymorphic model not getting saved (RAILS)


I can not for the life of me figure out why certain attributes of my paperclip attachment aren't not getting saved to the database via nested attributes. My post has one attachment but the :media params for the :attachment attribute not being saved, but the attachment object is being created. I figure I have something messed up with the way my strong params are being passed in. Thanks in advance.

NIL Params

  media_file_name: nil, media_content_type: nil, media_file_size: nil, media_updated_at: nil>

IRB:

 irb(main):001:0> p = Post.last
      Post Load (0.1ms)  SELECT  "posts".* FROM "posts"  ORDER BY "posts"."id" DESC LIMIT 1
    => #<Post id: 40, body: "test info", expiration: 1467065130586, created_at: "2016-06-27 21:05:41", updated_at: "2016-06-27 21:05:41">
    irb(main):002:0> p.attachment
      Attachment Load (0.2ms)  SELECT  "attachments".* FROM "attachments" WHERE "attachments"."attachable_id" = ? AND "attachments"."attachable_type" = ? LIMIT 1  [["attachable_id", 40], ["attachable_type", "Post"]]
    => #<Attachment id: 26, attachable_id: 40, attachable_type: "Post", created_at: "2016-06-27 21:05:41", updated_at: "2016-06-27 21:05:41", media_file_name: nil, media_content_type: nil, media_file_size: nil, media_updated_at: nil>
    irb(main):003:0> 

Schema:

ActiveRecord::Schema.define(version: 20160627165514) do

  create_table "attachments", force: :cascade do |t|
    t.integer  "attachable_id"
    t.string   "attachable_type"
    t.datetime "created_at",         null: false
    t.datetime "updated_at",         null: false
    t.string   "media_file_name"
    t.string   "media_content_type"
    t.integer  "media_file_size"
    t.datetime "media_updated_at"
  end

  add_index "attachments", ["attachable_type", "attachable_id"], name: "index_attachments_on_attachable_type_and_attachable_id"

  create_table "posts", force: :cascade do |t|
    t.text     "body"
    t.integer  "expiration", limit: 8
    t.datetime "created_at",           null: false
    t.datetime "updated_at",           null: false
  end

end

Post Model:

class Post < ActiveRecord::Base
    has_one :attachment, as: :attachable, dependent: :destroy
    accepts_nested_attributes_for :attachment
end

Post Controller:

class PostsController < ApplicationController

    def show
        #I don't need this.
    end

    def index
        @posts = Post.all
    end

    def new
        @post = Post.new
        @post.build_attachment
    end

    def create
        @post = Post.new(post_params)
        @post.build_attachment
        if @post.save
            respond_to do |format|
                format.html {redirect_to(posts_path, notice:"Post succesfully created")}
                format.js  
            end
        else
            render :new
        end
    end


    private

    def post_params
      params.require(:post).permit(:body,:expiration, attachment_attributes: [:media])
    end


end

Attachment Model:

class Attachment < ActiveRecord::Base

    belongs_to :attachable, polymorphic:true
    has_attached_file :media
end

HTML FORM:

    <%=form_for(@post, url: posts_path, html:{multipart:true}) do |form|%>
        <%=form.text_area :body%>

        <%=fields_for(:attachment) do |ff|%>
            <%= ff.file_field :media %>
        <%end%>


    <%=form.hidden_field :expiration%>
    <%=form.submit "Post", class: "post-submit-button"%>



<%end%>

Log Dumb:

Started POST "/posts" for ::1 at 2016-06-27 16:05:41 -0500
Processing by PostsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"/b54OJOBJIaR551MAHDujCxjciI7OAx93EQAVrugCz0xtYnafaSH4widYOftZJUbDHLfmI6jly5eG5AxCCNJbQ==", "post"=>{"body"=>"test info", "expiration"=>"1467065130586"}, "attachment"=>{"media"=>"IMG_1004.jpg"}, "commit"=>"Post"}
   (0.1ms)  begin transaction
  SQL (0.3ms)  INSERT INTO "posts" ("body", "expiration", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["body", "test info"], ["expiration", 1467065130586], ["created_at", "2016-06-27 21:05:41.321484"], ["updated_at", "2016-06-27 21:05:41.321484"]]
  SQL (0.1ms)  INSERT INTO "attachments" ("attachable_type", "attachable_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["attachable_type", "Post"], ["attachable_id", 40], ["created_at", "2016-06-27 21:05:41.323335"], ["updated_at", "2016-06-27 21:05:41.323335"]]
   (1.4ms)  commit transaction
Redirected to http://localhost:3000/posts
Completed 302 Found in 8ms (ActiveRecord: 1.9ms)


Started GET "/posts" for ::1 at 2016-06-27 16:05:41 -0500
Processing by PostsController#index as HTML
  Rendered layouts/_user_menu.html.erb (0.1ms)
  Rendered posts/index.html.erb within layouts/application (1.8ms)
Completed 200 OK in 26ms (Views: 25.8ms | ActiveRecord: 0.0ms)

Solution

  • You're not binding your fields_for to your form. Try this:

    <%=form_for(@post, url: posts_path, html:{multipart:true}) do |form|%>
      <%=form.text_area :body%>
      <%= form.fields_for(:attachment) do |ff|%>
        <%= ff.file_field :media %>
      <% end %>
      <%=form.hidden_field :expiration%>
      <%=form.submit "Post", class: "post-submit-button"%>
    <%end%>