Ruby on Rails - 回形针回滚事务

Posted

技术标签:

【中文标题】Ruby on Rails - 回形针回滚事务【英文标题】:Ruby on Rails - paperclip rollback transaction 【发布时间】:2016-12-19 21:53:32 【问题描述】:

我使用回形针作为嵌套属性并尝试在创建模型时使用 f.submit 上传照片

照片模型属于_分类模型..

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"

问题是提交后我从回形针收到“回滚事务”。

还有一个奇怪的事情是,我居然可以去查看回形针提到的路径中保存的文件...

型号:

    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

控制器

    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

查看:

<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>

控制台输出:

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)

我在 f.submit 遇到的错误:

Photos classified must exist

【问题讨论】:

您正在渲染部分错误,错误是什么?此外,您可能想使用 Paperclip 自己的 validates_attachment_content_type 回调。 @Eric 我只是渲染一个 h1 说错误,我试图显示一些可能的错误但我失败了,但我猜这是另一个问题.. 我会搜索验证! 我也尝试通过控制台创建分类对象并且成功,但我没有填写任何字段,如果我取出回形针代码并尝试创建分类,它再次成功创建它! @Eric 我使用了您提出的验证,但仍然相同,我设置了一个 Ubuntu 环境并再次尝试,因为由于各种原因,Windows 面临许多问题! #create 你有@classified,所以在错误部分使用content_tag :p, @classified.errors.full_messages.join('\n') 【参考方案1】:

毕竟解决方案是 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

我认为出于某种原因在 rails 5 中,为了使 nested_attributes 起作用,您需要使用 inverse_of ,尽管我没有资格解释它。

【讨论】:

以上是关于Ruby on Rails - 回形针回滚事务的主要内容,如果未能解决你的问题,请参考以下文章

Ruby On Rails:获取回形针图像的 md5 哈希

带有回形针的 If 语句 | Ruby on Rails

Rails回滚事务

如何使 SET XACT_ABORT ON 回滚事务?

sql 事务自动回滚

mysql事务未commit