Ruby on Rails在运行gsub后批量更新数据库中的记录

时间:2011-11-25 11:19:49

标签: ruby-on-rails

这是一个由两部分组成的问题。第1部分询问我的结构是否正确(它正在工作,我只是想知道这是否是Rails的做事方式)。第2部分询问如何在本文的标题中实际完成问题,我们在这里:

我的Dvd模型中有以下结构:

def self.remove_parens 
    # we will remove the beginning parentheses from the entries sent to us by the parens method
    @dvds = self.parens # get the entries we need to edit
    @dvds.each do |dvd|
        @newDvds = dvd.title.gsub!(/^\([0-9]*\)/, '')
    end
end

在DvdsController文件中:

  def fixer
    @newDvds = Dvd.remove_parens
  end

在修复程序视图文件中:

<% 
  @newDvds.each do |dvd| 
    fullText = "#{dvd.title}"
%>

这很好用,我可以看到gsub的结果正在工作,并从标题中删除(245)之类的条目。

  1. 这是在Rails中做事的正确方法吗?将大部分代码放在模型中,然后让控制器简单地调用该函数?
  2. 我意识到这只是打印出更改,而不是将它们写回数据库。我想把它们写回数据库,我将如何实现这一目标?也许通过在Controller中对@newDvds调用更新操作(因为模型不知道更新方法)?
  3. Socjopata:我根据你的建议对我的模特进行了推荐:

    dvds = self.parens # get the entries we need to edit
    dvds.each do |dvd|
        fixedTitle = dvd.title.gsub!(/^\([0-9]*\)/, '') # this prints it out but doesn't change the entries in the table
        dvd.update_attribute(:title, fixedTitle) # this is supposed to update the attribute in the table
    end
    

    但它不更新数据,表中的数据仍然相同。

    我最终做的是这似乎可以解决问题:

    Dvd.update(dvd.dogTag, { :title => fixedTitle } )
    

    现在我需要修剪那个标题,所以我想我会说:

    fixedTitle = dvd.title.gsub!(/^\([0-9]*\)/, '').strip!
    

2 个答案:

答案 0 :(得分:0)

  1. 是的,逻辑应放在模型中。
  2. 那么是什么阻止您通过更新@dvds来增强remove_parens?像

    _instance_of_a_dvd_model.update_attribute(:title,_gsubbed_title)

  3. 此外,您不需要在模型中“@”您的局部变量。另外,为什么要在视图中设置fullText变量?你在某个地方使用它吗?如果是,那么你知道你的观点应该是无逻辑的吗?

答案 1 :(得分:0)

fixedTitle = dvd.title.gsub!(/^\([0-9]*\)/, '').strip!有一些微妙的问题,第一个是你的数据库没有得到更新的原因。

gsub!修改字符串并绕过(截至3.2.7)ActiveRecord知道实例是否已更改的方式。它认为您的DVD实例仍未更改,因此会跳过更新数据库。

比较

dvd.title.gsub!(/^\([0-9]*\)/, '')
dvd.changed? # => always false if no other changes were made

dvd.title = dvd.title.gsub(/^\([0-9]*\)/, '')
dvd.changed? # => true if title was changed

此外,在strip!返回时调用gsub!可能会很危险。如果gsub!没有替换,那么它将返回nil并且您将尝试在nil上调用strip!。在这种情况下,我认为你想要使用gsub(没有!)。