rel*_*eod 9 ruby-on-rails default-scope destroy
我相信这是Rails 3中的一个错误.我希望有人能指引我朝着正确的方向前进.下面发布的代码纯粹是为了说明这个问题.希望这不会混淆问题.
鉴于我有一个Post模型和一个Comment模型.发表has_many评论,评论发表于发帖.
在Post模型上设置default_scope,定义join()和where()关系.在这种情况下,()依赖于连接().
通常帖子不依赖于评论.再说一遍,我只想举一个简单的例子.当where()依赖于join()时,这可能是任何情况.
class Post < ActiveRecord::Base
has_many :comments, :dependent => :destroy
default_scope joins(:comments).where("comments.id < 999")
end
class Comment < ActiveRecord::Base
belongs_to :post, :counter_cache => true
end
Run Code Online (Sandbox Code Playgroud)
运行以下命令:
Post.update_all(:title => Time.now)
Run Code Online (Sandbox Code Playgroud)
生成以下查询,并最终抛出ActiveRecord :: StatementInvalid:
UPDATE `posts` SET `title` = '2010-10-15 15:59:27' WHERE (comments.id < 999)
Run Code Online (Sandbox Code Playgroud)
同样,update_all,delete_all,destroy_all的行为方式相同.当我的应用程序在尝试更新counter_cache时抱怨时,我发现了这种行为.最终深入研究update_all.
小智 7
我也有这个问题,但是我们真的需要能够在update_all复杂条件下使用default_scope(例如,没有默认范围,急切加载是不可能的,并且在任何地方粘贴命名范围都没有任何乐趣).我已经在我的修复程序中打开了一个拉取请求:
https://github.com/rails/rails/pull/8449
对于delete_all我已经引发了一个错误,如果有一个连接条件让你更明显你要做什么(而不是只是抛出连接条件并在所有东西上运行delete_all,你得到一个错误).
不知道有什么轨道人员会对我的拉动请求做些什么,但认为这与这个讨论有关.(另外,如果您需要修复此错误,可以尝试我的分支并在拉取请求上发表评论.)
我也遇到了这个。
\n\n如果你有
\n\nclass Topic < ActiveRecord::Base\n default_scope :conditions => "forums.preferences > 1", :include => [:forum]\nend\nRun Code Online (Sandbox Code Playgroud)\n\n你做了一个
\n\nTopic.update_all(...)\nRun Code Online (Sandbox Code Playgroud)\n\nit\xe2\x80\x99 将失败
\n\nMysql::Error: Unknown column \'forums.preferences\' in \'where clause\'\nRun Code Online (Sandbox Code Playgroud)\n\n解决这个问题的方法是:
\n\nTopic.send(:with_exclusive_scope) { Topic.update_all(...) }\nRun Code Online (Sandbox Code Playgroud)\n\n您可以使用此代码进行猴子修补(并在environment.rb或其他地方需要它)
\n\nmodule ActiveRecordMixins\n class ActiveRecord::Base\n def self.update_all!(*args)\n self.send(:with_exclusive_scope) { self.update_all(*args) }\n end\n def self.delete_all!(*args)\n self.send(:with_exclusive_scope) { self.delete_all(*args) }\n end\n end\nend\nRun Code Online (Sandbox Code Playgroud)\n\n结尾
\n\n然后你就 update_all 了!或删除全部!当它有默认范围时。
\n