Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.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 3 Rails3AR:保存和更新方法不保存数据库中更改的属性,但不保存内存中的对象?_Ruby On Rails 3_Activerecord - Fatal编程技术网

Ruby on rails 3 Rails3AR:保存和更新方法不保存数据库中更改的属性,但不保存内存中的对象?

Ruby on rails 3 Rails3AR:保存和更新方法不保存数据库中更改的属性,但不保存内存中的对象?,ruby-on-rails-3,activerecord,Ruby On Rails 3,Activerecord,考虑以下情况: 蝴蝶=蝴蝶。创建(:color='blue') Butterfly.update_all(:color='red') 此时,正如预期的那样,蝴蝶(内存中)是蓝色的,而相应的数据库对象是红色的。现在尝试更新数据库条目 butterfly.update_属性(:size=>big) 结果是“大小”属性会更新,但颜色不会更新。我们面临的情况是,即使在成功保存或更新_属性之后,数据库也与内存中的对象不匹配。事实上,即使是butterfly.update_属性(:color,'blue')

考虑以下情况:

  • 蝴蝶=蝴蝶。创建(:color='blue')
  • Butterfly.update_all(:color='red')
  • 此时,正如预期的那样,蝴蝶(内存中)是蓝色的,而相应的数据库对象是红色的。现在尝试更新数据库条目

  • butterfly.update_属性(:size=>big)
  • 结果是“大小”属性会更新,但颜色不会更新。我们面临的情况是,即使在成功保存或更新_属性之后,数据库也与内存中的对象不匹配。事实上,即使是
    butterfly.update_属性(:color,'blue')
    也不足以强制更改数据库!我认为强制执行的唯一方法是首先将属性更新为其他属性(
    butterfly.update_属性(:color,'anything')
    ),然后将其更改回原始值

    事情就是这样吗?

    有点像

    Model.update\u all
    直接向基础数据库发出更新查询;它不会更新内存中已有的任何实例。类似地,
    instance.update\u attributes
    只更新它,不从数据库重新获取,因为它假定实例已经具有最新的属性值

    这通常适用于Rails,实例通常是短暂的:它们只存在于请求的范围内,并且在大多数情况下,它们直接被操作

    在您上面描述的情况下,您需要额外的步骤-
    Model#reload
    将执行您想要的操作:

    # create our instance
    @butterfly = Butterfly.create(color: 'blue') # => #<Butterfly id: 100, color: 'blue'>
    
    Butterfly.update_all(color: 'red')
    
    # We now have a mis-match between our instance and our database. Our instance 
    # is still blue, but the database says it should be red. Reloading it...
    
    @butterfly.reload # => #<Butterfly id: 100, color: 'red'>
    
    # And we can now re-update our butterfly
    @butterfly.update_attributes(size: 'big') # => #<Butterfly id: 100, color: 'red', size: 'big'>
    
    #创建我们的实例
    @蝴蝶=蝴蝶。创建(颜色:“蓝色”)#=>#
    蝴蝶。全部更新(颜色:“红色”)
    #现在,我们的实例和数据库之间存在不匹配。我们的例子
    #仍然是蓝色的,但数据库说应该是红色的。重新加载它。。。
    @butterfly.reload#=>#
    #现在我们可以重新更新我们的蝴蝶
    @butterfly.update_属性(大小:'big')#=>#
    

    如果您使用的是
    update\u all
    ,最好看看是否有可能在加载实例之前构建代码。

    谢谢。是的,这就是我认为正在发生的事情,但我并不认为事情应该是这样的。在我的例子中,我不想将值保留在数据库中,我想将值保留在模型中,因此重载没有帮助。事实上,我无意中发现了这一点,因为我想这样做:在保存之前,如果蝴蝶被标记为“最好的”,则从数据库中的所有其他蝴蝶中清除“最好的”。这似乎是确保只有一只蝴蝶具有“最佳”属性的简单方法。相反,我可以使用update_all(:the_best=>false,“id!={self.id}”),但这似乎不必要。我想基本的问题是,为什么不“save”或至少一个显式的“update_属性”像人们所期望的那样保存到数据库中,不要只将对象中未更改的属性保存在内存中?如果您的规则是在任何时间只有一个蝴蝶可以标记为“最佳”,请尝试以下操作:Butterfly.update_all({the_best:false},{the_best:true})@new_best=Butterfly.find(params[:id])@新的最佳。更新最佳属性(最佳:true);至于原因,我真的不知道。