Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/57.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 保存后Rails方法尝试反复更新记录_Ruby On Rails_Ruby_Methods_Model_Open Uri - Fatal编程技术网

Ruby on rails 保存后Rails方法尝试反复更新记录

Ruby on rails 保存后Rails方法尝试反复更新记录,ruby-on-rails,ruby,methods,model,open-uri,Ruby On Rails,Ruby,Methods,Model,Open Uri,我遇到了一个奇怪的问题,我的应用程序似乎陷入了一个循环 我有一个名为Pages的模型,允许用户在保存时输入URL。我有一个名为process_Pages的after_save方法,如下所示 pages.rb(模型) class页面

我遇到了一个奇怪的问题,我的应用程序似乎陷入了一个循环

我有一个名为Pages的模型,允许用户在保存时输入URL。我有一个名为process_Pages的after_save方法,如下所示

pages.rb(模型)
class页面
在保存URL时,我可以在开发控制台中看到,它获取了站点的HTML,但不断尝试保存记录,一次又一次地暂停页面,我必须手动退出服务器

当我再次开始备份时,记录已被添加,并按预期工作,直到我添加另一个URL

我的代码是否存在任何可能导致此连续循环的错误


谢谢你的阅读

那么self.url是否指向页面url?如果是这样的话,当您保存它时,它会点击页面的服务器,这可能会导致另一个保存和另一个url请求,等等。

那么self.url是否指向页面url?如果是这样,当你保存它时,它会点击你的服务器获取页面,这可能会导致另一个保存和另一个url请求,等等。

如果在创建
页面
记录之后,而不是更新页面记录之后,您只需要调用
处理页面
一次,那么我建议在创建
之后使用

class Page < ActiveRecord::Base
  require 'open-uri'

  after_create :process_pages

  def process_pages
    self.html = open(self.url).read
    self.save
  end 
end
class页面
使用
after\u save:process\u pages
,每次保存页面记录时都会调用
process\u pages
方法。您正在
process\u pages
方法中再次保存一条页面记录,该方法在\u save
回调后触发
,并开始循环

有关,请参见此SO问题。
您将更好地理解为什么要进行循环。

如果您需要在创建
页面
记录后只调用
处理页面
一次,而不是在更新页面记录后,那么我建议改为在创建
后使用

class Page < ActiveRecord::Base
  require 'open-uri'

  after_create :process_pages

  def process_pages
    self.html = open(self.url).read
    self.save
  end 
end
class页面
使用
after\u save:process\u pages
,每次保存页面记录时都会调用
process\u pages
方法。您正在
process\u pages
方法中再次保存一条页面记录,该方法在\u save
回调后触发
,并开始循环

有关,请参见此SO问题。
您将更好地理解为什么要进行循环。

这是因为您一直在重新保存循环。相反,你应该:

def process_pages
  update_column(:html, open(self.url).read)
end
update\u column
正在将一列保存到数据库,跳过所有回调,因此它不会在保存回调后重新触发您的回调。然而,在保存过滤器之前,您可以使用
执行一个查询,而执行两个查询是毫无意义的:

before_save :process_pages

def process_pages
  self.html = open(self.url).read
end 
但最好的方法可能是覆盖
url
方法的setter:

def url=(value)
  super
  self.html = open(self.url).read
end

这样,您可以在保存模型之前使用页面html。

这是因为您一直在重新保存它。相反,你应该:

def process_pages
  update_column(:html, open(self.url).read)
end
update\u column
正在将一列保存到数据库,跳过所有回调,因此它不会在保存回调后重新触发您的回调。然而,在保存过滤器之前,您可以使用
执行一个查询,而执行两个查询是毫无意义的:

before_save :process_pages

def process_pages
  self.html = open(self.url).read
end 
但最好的方法可能是覆盖
url
方法的setter:

def url=(value)
  super
  self.html = open(self.url).read
end

通过这种方式,您可以在保存模型之前使用页面html。

您陷入了一个循环,因为您的回调在保存后被触发,然后方法定义本身正在调用保存,导致回调再次触发

你有一些选择。您可以在保存前将回调更改为

class Page < ActiveRecord::Base
  require 'open-uri'

  before_save :process_pages

  def process_pages
    self.html = open(self.url).read
  end 
end
class页面
您可以在创建后更改为
回调,该回调仅在记录创建且未更新时触发,但这可能不是所需的行为


您也可以通过调用
update\u column
跳过回调,而不是调用
save
,正如所指出的那样。您陷入了一个循环中,因为您的回调在save
之后被触发,然后方法定义本身正在调用save,导致回调再次触发

你有一些选择。您可以在保存前将回调更改为

class Page < ActiveRecord::Base
  require 'open-uri'

  before_save :process_pages

  def process_pages
    self.html = open(self.url).read
  end 
end
class页面
您可以在创建后更改为
回调,该回调仅在记录创建且未更新时触发,但这可能不是所需的行为


您也可以通过调用
update\u column
来跳过回调,而不是调用
save
,正如

所指出的,答案中有很多解决方法,但我想指出,您遇到了这个问题,因为您的模型做得太多了。如果您将模型视为数据库的接口,而不是可以在控制器之外访问的业务逻辑的转储场,那么您将最终创建更精简的对象,而这些对象本身(以及彼此)不会发生绊倒。谢谢@coreyward。我说的对吗?那么这种方法应该在我的项目的其他地方进行?是的,绝对正确。不幸的是,栏杆提供了很多绳子,鼓励你上吊。对于这种特殊的行为,你可能会得到最好的服务