ActiveRecord .save返回true但不保存?

时间:2015-05-05 11:28:22

标签: ruby-on-rails ruby activerecord

我按照上一个问题的答案重构我的代码: Inheritance misunderstood (仅供参考,此问题与其他内容有关)

所以我确实创建了'存档'模块。

module Archive
def self.included(klass)
 klass.instance_eval do
   define_method "save_#{klass.name}_archive" do
     ArchiveLogs.debug("PASS HERE")
     self.becomes "Arch#{klass.name}".constantize
    end
   end
  end
end

我在这里使用它:

     ArchiveLogs.debug("DEV BEGIN")

     ArchiveLogs.debug("DEV inspect content"+content.inspect)
     archived_content = content.save_Content_archive
     ArchiveLogs.debug("DEV inspect archived"+archived_content.inspect)
     test = archived_content.save
     test2 = archived_content.save!


     ArchiveLogs.debug("DEV WORK ?"+test.inspect)
     ArchiveLogs.debug("DEV  WORK 2?"+test2.inspect)

这是我的日志

 DEV BEGIN
DEV inspect content#<Content id: 1653768, server_path: "20141219/M2014121900660", server_name: "content.html", is_html: 1, checksum: #<BigDecimal:62433c0,'0.1307989417E10',18(27)>, save_date: nil, save_place: nil, user_id: nil, created_at: "2015-03-31 11:29:43",  updated_at: "2015-03-31 11:29:43", ts_content: nil>
PASS HERE
DEV inspect archived#<ArchContent id: 1653768, server_path: "20141219/M2014121900660", server_name: "content.html", is_html: 1, checksum: #<BigDecimal:624a9e0,'0.1307989417E10',18(27)>, save_date: nil, save_place: nil, user_id: nil, created_at: "2015-03-31 11:29:43",  updated_at: "2015-03-31 11:29:43", ts_content: nil>
DEV WORK ?true
DEV  WORK 2?true

内容模型:

class Content < ActiveRecord::Base
   has_many :information
   attr_accessor :text_content
   include Archive
  . 
  . 
  .#many methods here
  .
  .
end

Arch内容模型:

class ArchContent < ActiveRecord::Base
  set_table_name 'archive.contents'
  has_many :information, :class_name => 'ArchInformation',foreign_key: 'content_id'
  include Archive
  . 
  . 
  .#many methods here
  .
  .
end

如你所见,我的档案模块完成了他的工作。当我给他Content对象时创建ArchContent对象。

但这是我的问题.save返回true,但我的archived_content不存储在我的数据库中。为什么?

我确实在帖子Rails save returns true but doesn't save anything

上读到过类似问题

关于强制我使用update_column的验证问题。

所以我的问题:

我被迫使用update_column吗?或者我的问题是别的什么?怎么调试这个? 任何帮助都是有用的!

4 个答案:

答案 0 :(得分:2)

becomes复制所有记录的状态,在你的情况下是太多了:它复制new_record标志(因此rails认为这个对象在数据库中持久存在事实上并非如此)并且它复制属性更改数据(因此rails认为没有任何列更改了数据)。

结果是rails认为没有什么新东西可以保存,所以对save的调用没有做任何事情。即使您将属性标记为脏,它也会尝试进行更新而不是插入,因为new_record?将为false。据我所知,没有设置new_record的公开API,所以我不确定如何使其工作。

答案 1 :(得分:1)

查看您的项目是否有效以及您的日志中是否有任何验证错误:

Rails.logger.info archived_content.valid?
test = archived_content.save
Rails.logger.info archived_content.errors.full_messages

并回复结果。

答案 2 :(得分:1)

首先感谢@FrederickCheung的解释,以及@papirtiger的underscore注释, 我想我找到了一个更好的解决方案来解决这个问题,你可以使用#attributes来返回带有属性而不是对象的哈希

define_method "save_#{klass.name.underscore}_archive" do
  "Arch#{klass.name}".constantize.new attributes.except('id')
end

这将返回一个带有属性的未保存对象,它将删除id键,使其遵循另一个表的正常自动增量方案。

答案 3 :(得分:0)

仔细检查您的模型on_update挂钩。在我的情况下,它不是一个错误,它是一个更新钩子,重置我试图坚持的价值。

所以它最终不是Rails问题,只是我的业务逻辑问题。