我写了一个回调 after_save :import,上传文件后会创建该文件的一些属性 name, content-type 之类的,import 是为了在创建这些文件属性并保存后执行的方法。是用的一个插件,没法定制方法用 form_for 之类的来接受参数。
:import 方法是用来获取上传的 excel 文件,并解析里面的数据,并且将需要 2 条数据存入数据库 (使用的是 update_attributes)。测试时,excel 里面有 2 条数据。使用的 each 来迭代处理。
查看了文档,是因为回调里的操作都是在一个事物里,所以我这里,用了 each 迭代两次就不是在一个事务里,第一个 update_attributes 完成后 rails 认为这一个事务完成了,于是该终止执行了,但 each 又开始迭代,所以数据库会终止事务,执行 rollback
所以解决方案是想办法把所有需要修改的数据处理在一个事务里?
(0.3ms) UPDATE `select_items` SET `excel_file_name` = 'Excelfile.xls', `updated_at` = '2015-11-30 12:46:01' WHERE `select_items`.`id` = 1
SelectItem Load (1.9ms) SELECT `select_items`.* FROM `select_items` WHERE `select_items`.`id` = 1 LIMIT 1
(2.5ms) ROLLBACK
Completed 500 Internal Server Error in 102ms
TypeError (can't convert nil into String):
app/models/select_item.rb:32:in `+'
app/models/select_item.rb:32:in `import'
app/models/select_item.rb:47:in `block in import'
app/models/select_item.rb:36:in `each'
app/models/select_item.rb:36:in `import'
Rendered /var/lib/gems/1.9.1/gems/actionpack-3.2.14/lib/action_dispatch/middleware/templates/rescues/_trace.erb (3.1ms)
Rendered /var/lib/gems/1.9.1/gems/actionpack-3.2.14/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.1ms)
Rendered /var/lib/gems/1.9.1/gems/actionpack-3.2.14/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (10.2ms)
Started GET "/buyer/select_items/2/edit?select_list_id=1&association=select_items&parent_scaffold=buyer/select_lists&select_list_id=1&adapter=_list_inline_adapter" for 127.0.0.1 at 2015-11-30 12:46:27 +0800
Processing by Buyer::SelectItemsController#edit as JS
Parameters: {"select_list_id"=>"1", "association"=>"select_items", "parent_scaffold"=>"buyer/select_lists", "adapter"=>"_list_inline_adapter", "id"=>"2"}
Creating scope :seller_admin. Overwriting existing method User.seller_admin.
User Load (1.6ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
SelectList Load (0.1ms) SELECT `select_lists`.* FROM `select_lists` WHERE `select_lists`.`id` = 1 LIMIT 1
SelectItem Load (0.4ms) SELECT `select_items`.* FROM `select_items` WHERE `select_items`.`select_list_id` = 1 AND `select_items`.`id` = 2 LIMIT 1
Rendered /var/lib/gems/1.9.1/gems/active_scaffold-3.3.3/app/views/active_scaffold_overrides/_form_messages.html.erb (0.3ms)
Rendered /var/lib/gems/1.9.1/gems/active_scaffold-3.3.3/app/views/active_scaffold_overrides/_form.html.erb (8.0ms)
Rendered /var/lib/gems/1.9.1/gems/active_scaffold-3.3.3/app/views/active_scaffold_overrides/_base_form.html.erb (15.1ms)
Rendered /var/lib/gems/1.9.1/gems/active_scaffold-3.3.3/app/views/active_scaffold_overrides/_update_form.html.erb (17.8ms)
Rendered /var/lib/gems/1.9.1/gems/active_scaffold-3.3.3/app/views/active_scaffold_overrides/_messages.html.erb (0.1ms)
Rendered /var/lib/gems/1.9.1/gems/active_scaffold-3.3.3/app/views/active_scaffold_overrides/_list_inline_adapter.html.erb (2.5ms)
Completed 200 OK in 304ms (Views: 5.4ms | ActiveRecord: 7.3ms | Solr: 0.0ms)
Started PUT "/buyer/select_items/2?association=select_items&iframe=true&parent_scaffold=buyer%2Fselect_lists&select_list_id=1" for 127.0.0.1 at 2015-11-30 12:46:31 +0800
Processing by Buyer::SelectItemsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"NOQy+DATRkkOoCyrfgsDDkLUq4ey0lvsUzFiGzfOG9g=", "record"=>{"op_platform"=>"op2", "select_location"=>"sl2", "excel"=>#<ActionDispatch::Http::UploadedFile:0xb3e348e8 @original_filename="'Excelfile.xls", @content_type="application/vnd.ms-excel", @headers="Content-Disposition: form-data; name=\"record[excel]\"; filename=\"\xE5\x88\x86\xE6\x8B\xA3\xE5\x8D\x95_20151130095730.xls\"\r\nContent-Type: application/vnd.ms-excel\r\n", @tempfile=#<File:/tmp/RackMultipart20151130-4227-7a78ap>>}, "commit"=>"Update", "association"=>"select_items", "iframe"=>"true", "parent_scaffold"=>"buyer/select_lists", "select_list_id"=>"1", "id"=>"2"}
User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
SelectList Load (0.1ms) SELECT `select_lists`.* FROM `select_lists` WHERE `select_lists`.`id` = 1 LIMIT 1
SelectItem Load (0.1ms) SELECT `select_items`.* FROM `select_items` WHERE `select_items`.`select_list_id` = 1 AND `select_items`.`id` = 2 LIMIT 1
(0.1ms) BEGIN
Order Load (0.1ms) SELECT `orders`.* FROM `orders` WHERE `orders`.`id` = 1 LIMIT 1
CACHE (0.0ms) SELECT `select_lists`.* FROM `select_lists` WHERE `select_lists`.`id` = 1 LIMIT 1
(0.4ms) UPDATE `select_items` SET `excel_file_name` = NULL, `updated_at` = '2015-11-30 12:46:31' WHERE `select_items`.`id` = 2
SelectItem Load (0.3ms) SELECT `select_items`.* FROM `select_items` WHERE `select_items`.`id` = 1 LIMIT 1
(2.3ms) ROLLBACK
Completed 500 Internal Server Error in 176ms
TypeError (can't convert nil into String):
app/models/select_item.rb:30:in `+'
app/models/select_item.rb:30:in `import'
app/models/select_item.rb:44:in `block in import'
app/models/select_item.rb:33:in `each'
app/models/select_item.rb:33:in `import'