Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何在ActiveRecord验证失败后将某些内容保存到数据库?_Ruby On Rails_Ruby_Validation_Activerecord - Fatal编程技术网

Ruby on rails 如何在ActiveRecord验证失败后将某些内容保存到数据库?

Ruby on rails 如何在ActiveRecord验证失败后将某些内容保存到数据库?,ruby-on-rails,ruby,validation,activerecord,Ruby On Rails,Ruby,Validation,Activerecord,基本上,我想做的是在MyModelLog表中记录MyModel上的操作。下面是一些伪代码: class MyModel < ActiveRecord::Base validate :something def something # test errors.add(:data, "bug!!") end end classmymodelEvent.new.save =>错误 >>EventLog.all => [#] >>事件。全部 => [] 也许我

基本上,我想做的是在MyModelLog表中记录MyModel上的操作。下面是一些伪代码:

class MyModel < ActiveRecord::Base
  validate :something

  def something
     # test
     errors.add(:data, "bug!!")
  end
end
classmymodel
我还有一个这样的模型:

class MyModelLog < ActiveRecord::Base

  def self.log_something
    self.create(:log => "something happened")
  end

end
def something
    error = nil
    ActiveRecord::Base.transaction do
        begin
            # place codez here
        rescue ActiveRecord::Rollback => e
            error = e.message
            raise ActiveRecord::Rollback
        end
    end
    MyModelLog.log_something(error) unless error.nil?
end
classmymodellog“发生了什么事”)
结束
结束
为了记录日志,我尝试:

  • MyModel

  • MyModel的
    callback验证后,在
    上调用
    MyModelLog.log\u something

在这两种情况下,当验证失败时,创建将回滚,因为它位于验证事务中。当然,我还想在验证失败时记录日志。我真的不想登录到文件或数据库以外的其他地方,因为我需要日志条目与其他模型的关系以及执行请求的能力


我的选项是什么?

您可以使用嵌套事务。这样,回调中的代码在与验证失败不同的事务中执行。的Rails文档讨论了如何做到这一点。

我不确定它是否适用于您,但我假设您正在尝试从控制器保存/创建模型。在控制器中,很容易检查该操作的结果,并且您很可能已经为用户提供了一个有用的闪光灯;因此,您可以轻松地在那里记录适当的消息

我还假设您不使用任何显式事务,因此如果您在控制器中处理它,它就在事务之外(每个save和destroy都在自己的事务中工作)


你觉得怎么样?

这是否适合一个年轻人?我不确定,但我希望这不在交易范围内。。。我有一个类似的需求,我可能想在更新时删除一条记录…

嵌套事务似乎在MySQL中工作

下面是我在一个新生成的rails(使用MySQL)项目上尝试的内容:

/script/生成模型事件标题:字符串--跳过时间戳--跳过夹具
./script/生成模型事件日志错误\u消息:文本--跳过夹具
类事件event.errors.on(:title)
connection.execute('COMMIT'))
结束
结束
#然后在脚本/控制台中:
>>Event.new.save
=>错误
>>EventLog.all
=> [#]
>>事件。全部
=> []

也许我过于简化了,或者遗漏了一些要点

MyModelLog.log\u应该使用不同的连接来完成某些操作

您可以通过使用建立连接使MyModelLog模型始终使用不同的连接

class MyModelLog < ActiveRecord::Base
  establish_connection Rails.env # Use different connection

  def self.log_something
    self.create(:log => "something happened")
  end
end
classmymodellog“发生了什么事”)
结束
结束

不确定这是否是进行日志记录的正确方法

我利用Ruby的变量作用域解决了这样一个问题。基本上,我在一个事务块之外声明了一个
error
变量,然后捕获、存储日志消息并再次引发错误

它看起来像这样:

class MyModelLog < ActiveRecord::Base

  def self.log_something
    self.create(:log => "something happened")
  end

end
def something
    error = nil
    ActiveRecord::Base.transaction do
        begin
            # place codez here
        rescue ActiveRecord::Rollback => e
            error = e.message
            raise ActiveRecord::Rollback
        end
    end
    MyModelLog.log_something(error) unless error.nil?
end

通过将
error
变量声明在事务范围之外,即使在事务退出后,变量的内容仍然存在。

类似的问题:我可能不理解您的观点,但如果我为日志执行嵌套事务,那么当“父”事务回滚时,孩子也会被回滚好主意,我会考虑一下,看看它是否符合我要做的事情。进一步的研究表明,这可能不起作用——甚至观察者也会在事务内部进行。看看rails 3中的after_commit,在提交之后运行一些东西。。。还有一个后回滚谢谢你的回答,但是我可能会在不同的地方有很多这样的日志,所以我更愿意将它们保存在我的模型中。在控制器中执行此操作的优点是它是显式的,并且