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 - 回形针回滚事务的主要内容,如果未能解决你的问题,请参考以下文章