Ruby on Rails - paperclip rollback transaction
Asked Answered
U

1

9

Im using paperclip as a nested attribute and trying to upload the photo at the model creation with f.submit

The photos model belongs_to classified model..

c:\Site\brokerv1\brokr>rails --version
Rails 5.0.0


c:\Site\brokerv1\brokr>ruby -v
ruby 2.2.4p230 (2015-12-16 revision 53155) [i386-mingw32]


gem "paperclip", "~> 4.2"

Problem is that after the submission i get a "rollback transaction" from paperclip.

Another weird thing is that i can actually go and see the file saved in the path mentioned by paperclip...

models:

    class Photo < ApplicationRecord

    belongs_to :classified

    has_attached_file :image, :styles => { :large => "600x170", :medium => "250x250!",:thumb => "100x100>" }, :default_url => lambda { |photo| photo.instance.set_default_url}
    validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]

    validates_attachment_presence :datafile unless :datafile
end


    class Classified < ApplicationRecord
    belongs_to :user

    has_many :photos
    accepts_nested_attributes_for :photos



end

Schema.rb

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

  create_table "classifieds", force: :cascade do |t|
    t.string   "make"
    t.string   "model"
    t.string   "year"
    t.string   "color"
    t.string   "title"
    t.string   "condition"
    t.string   "price"
    t.string   "offer"
    t.string   "make_country"
    t.string   "category"
    t.text     "description"
    t.integer  "user_id"
    t.datetime "created_at",   null: false
    t.datetime "updated_at",   null: false
    t.index ["user_id"], name: "index_classifieds_on_user_id"
  end

  create_table "photos", force: :cascade do |t|
    t.integer  "classified_id"
    t.datetime "created_at",         null: false
    t.datetime "updated_at",         null: false
    t.string   "image_file_name"
    t.string   "image_content_type"
    t.integer  "image_file_size"
    t.datetime "image_updated_at"
    t.index ["classified_id"], name: "index_photos_on_classified_id"
  end

  create_table "users", force: :cascade do |t|
    t.string   "first_name"
    t.string   "email"
    t.string   "password_digest"
    t.datetime "created_at",      null: false
    t.datetime "updated_at",      null: false
  end

end

Controller

    class ClassifiedsController < ApplicationController


    before_action :require_user, only: [:index, :show]


    def new 
        @classified = Classified.new
        @photo = @classified.photos.build
    end

    def index
        @classified = Classified.all
    end

    def show 
        @classified = Classified.find(params[:id])
    end


    def edit
        @classified = Classified.find(params[:id])

    end

    def update
        @classified = Classified.find(params[:id])

        if @classified.update_attributes(classified_params)

          redirect_to '/'
        else
          redirect_to '/'
        end   
    end

    def destroy
        flash[:success] = "deleted"
        if Classified.find(params[:id]).destroy
            redirect_to '/'
        else
            redirect_to '/'
        end
    end

    def create

        @classified = Classified.new(classified_params)
        @classified.user_id = current_user.id


        if @classified.save
            redirect_to '/'
        else
            render 'create'
        end         


    end




private


    def classified_params
        params.require(:classified).permit(:make ,:model,:year,:color,:title,:condition,:price,:offer,:make_country ,:category  ,:description ,:photos_attributes => [:id , :image , :classified_id ]   )
    end
end

View:

<div class="new">
  <div class="container-fluid">

    <section class="container">
      <div class="container-page">  

        <div class="col-md-6">
          <h3 class="dark-grey">Εξοπλισμός προς πώληση</h3>
          <%= form_for (@classified) , :html => { :multipart => true } do |f| %>  

          <% if @classified.errors.any? %>
          <div id="error_explanation">
            <h2>
              <%= pluralize(@classified.errors.count, "error") %> prohibited
              this article from being saved:
            </h2>
            <ul>
              <% @classified.errors.full_messages.each do |msg| %>
              <li><%= msg %></li>
              <% end %>
            </ul>
          </div>
          <% end %>

          <div class="form-group col-lg-3">
            <label>Μάρκα</label>
            <%= f.text_field :make, :placeholder => "π.χ. Fender" , :class => "form-control"%>
          </div>

          <div class="form-group col-lg-6">
            <label>Μοντέλο</label>
            <%= f.text_field :model, :placeholder => "π.χ. Stratocaster" , :class => "form-control"%>
          </div>  

          <div class="form-group col-lg-3">
            <label>Έτος</label>
            <%= f.text_field :year, :placeholder => "π.χ. 1992" , :class => "form-control"%>
          </div>

          <div class="form-group col-lg-12">
            <label>Τίτλος Αγγελίας</label>
            <%= f.text_field :title, :placeholder => "" , :class => "form-control"%>
          </div>

          <div class="form-group col-lg-5">
            <label>Κατάσταση</label>
            <%= f.text_field :condition, :placeholder => "" , :class => "form-control"%>
          </div>

          <div class="form-group col-lg-4">
            <label>Χώρα κατασκευής</label>
            <%= f.text_field :make_country, :placeholder => "" , :class => "form-control"%>
          </div>

          <div class="form-group col-lg-3">
            <label>Τιμή</label>
            <%= f.text_field :price, :placeholder => "" , :class => "form-control"%>
          </div>

          <div class="form-group col-lg-12">

           <h3 class="dark-grey">Περιγραφή</h3>
           <%= f.text_area :description, rows: "15", :placeholder => "" , :class => "form-control"%>
         </div>





         <div class="form-group col-lg-12">

           <h3 class="dark-grey">Φωτογραφίες</h3>


           <%= f.fields_for :photos do |p| %>

           <%= p.file_field :image %>

           <% end %>

         </div>




         <div class="linkbtn">
           <%= f.submit nil, class: "btn-submit" %>
           <% end %>
         </div>

       </div>

Console output:

Processing by ClassifiedsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"Xar6eiClpg4EtaihHCsKuPvfHZjOLgagcXlkB6EW3YO5UKgKzSU+Xo5+4EGVKPzljsGLE6p/JxVeQBNLVAZOSw==", "classified"=>{"make"=>"kdhf", "model"=>"yid", "year"=>"dtyi", "title"=>"dtyi", "condition"=>"dyti", "make_country"=>"dtyi", "price"=>"tydi", "description"=>"dyti", "photos_attributes"=>{"0"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x007f1ec21689c8 @tempfile=#<Tempfile:/tmp/RackMultipart20160815-15158-ed3vq1.JPG>, @original_filename="IMG_0367.JPG", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"classified[photos_attributes][0][image]\"; filename=\"IMG_0367.JPG\"\r\nContent-Type: image/jpeg\r\n">}}}, "commit"=>"Create Classified"}
Command :: file -b --mime '/tmp/8c1670d3211dcd380aba6a73797c0a1e20160815-15158-1y57b8t.JPG'
Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/8c1670d3211dcd380aba6a73797c0a1e20160815-15158-1wgarr9.JPG[0]' 2>/dev/null
Command :: identify -format %m '/tmp/8c1670d3211dcd380aba6a73797c0a1e20160815-15158-1wgarr9.JPG[0]'
Command :: convert '/tmp/8c1670d3211dcd380aba6a73797c0a1e20160815-15158-1wgarr9.JPG[0]' -auto-orient -resize "600x170" '/tmp/f7a62ccc518343a663edf66b07d7245c20160815-15158-572p8w'
Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/8c1670d3211dcd380aba6a73797c0a1e20160815-15158-1wgarr9.JPG[0]' 2>/dev/null
Command :: identify -format %m '/tmp/8c1670d3211dcd380aba6a73797c0a1e20160815-15158-1wgarr9.JPG[0]'
Command :: convert '/tmp/8c1670d3211dcd380aba6a73797c0a1e20160815-15158-1wgarr9.JPG[0]' -auto-orient -resize "250x250!" '/tmp/f7a62ccc518343a663edf66b07d7245c20160815-15158-yboo18'
Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/8c1670d3211dcd380aba6a73797c0a1e20160815-15158-1wgarr9.JPG[0]' 2>/dev/null
Command :: identify -format %m '/tmp/8c1670d3211dcd380aba6a73797c0a1e20160815-15158-1wgarr9.JPG[0]'
Command :: convert '/tmp/8c1670d3211dcd380aba6a73797c0a1e20160815-15158-1wgarr9.JPG[0]' -auto-orient -resize "100x100>" '/tmp/f7a62ccc518343a663edf66b07d7245c20160815-15158-13uo06a'
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 4], ["LIMIT", 1]]
   (0.1ms)  begin transaction
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 4], ["LIMIT", 1]]
Command :: file -b --mime '/tmp/8c1670d3211dcd380aba6a73797c0a1e20160815-15158-qz9itf.JPG'
   (0.1ms)  rollback transaction
  Rendering classifieds/create.html.erb within layouts/application
  Rendered classifieds/_gear.html.erb (4.9ms)
  Rendered classifieds/_description.html.erb (0.4ms)
  Rendered classifieds/create.html.erb within layouts/application (7.0ms)
Completed 200 OK in 422ms (Views: 37.6ms | ActiveRecord: 2.7ms)

And the error I'm getting at f.submit :

Photos classified must exist
Unconscionable answered 12/8, 2016 at 19:48 Comment(7)
You're rendering an errors partial, what is the error? Also, you probably want to use Paperclip's own validates_attachment_content_type callback.Kanishakanji
@Kanishakanji im just rendering an h1 saying error , i tried to show some possible errors but i failed , but that's another question i guess.. Ill search about the validation !Unconscionable
i also tried creating a classified object through the console and it was successful , but i did not fill any fields, also if i take out the paperclip code and try to create a classified , again it successfully creates it!Unconscionable
@Kanishakanji i used the validation you proposed but still the same, ill set up an Ubuntu environment and try again as many face issues with windows for various reasons!Unconscionable
In #create you have @classified, so in the errors partial use content_tag :p, @classified.errors.full_messages.join('\n')Kanishakanji
@Kanishakanji i managed to rewrite the code , and render the errors , and i get error : Photos classified must exist (when im f.submit)Unconscionable
@Kanishakanji ill edit my question for the current code!Unconscionable
U
2

after all the solution was inverse_of

 class Photo < ApplicationRecord

    belongs_to :classified,inverse_of: :photos

    has_attached_file :image, :styles => { :large => "600x170", :medium => "250x250!",:thumb => "100x100>" }, :default_url => lambda { |photo| photo.instance.set_default_url}
    validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]

    validates_attachment_presence :datafile unless :datafile
end


    class Classified < ApplicationRecord
    belongs_to :user

    has_many :photos,inverse_of: :classified
    accepts_nested_attributes_for :photos



end

i think for some reason in rails 5 , for nested_attributes to work , you need to use inverse_of , though im not qualified to explain it.

Unconscionable answered 15/8, 2016 at 21:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.