Rails - 避免自动保存关联

时间:2012-11-27 08:37:40

标签: ruby-on-rails-3 build associations

我的模型及其关联是:

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post
  validates :commenter, :presence => true
end

案例1 :当我尝试下面的代码时,会调用自动保存方法。

@post = Post.find(3)
@comments = @post.comments
p @comments #=> []
p @comments.class #=> Array
if @comments.empty?
  3.times do
    @comments << @post.comments.build
 end
end
p @comments.first.errors #=>{:commenter=>["can't be blank"]}

案例2:如果我手动将相同的空数组初始化为@comments,则自动保存不会调用。例如,

p @comments #=> []
p @comments.class #=> Array
if @comments.empty?
  @comments = []
  p @comments #=> []
  3.times do
    @comments << @post.comments.build
  end
end
p @comments.first.errors #=>{}

什么是避免自动保存的最佳解决方案,请任何人解释为什么上述代码的行为不同?

2 个答案:

答案 0 :(得分:1)

Rails广泛使用monkey-patching,因此rails Array与纯Ruby数组不同。 (比较irb > [].methodsrails c > [].methods

的输出

根据<<集合

documentation has_many方法
  

立即触发update sql而不等待保存或更新调用   在父对象上

因此,很可能Rails拥有集合事件的“观察者”,并在您尝试添加新对象时触发验证。

在第二个片段中,您使用纯数组(不是has_many集合),因此不会触发更新操作。

为避免更新操作,您根本不需要<<

@post = Post.find(3)
@comments = @post.comments
if @comments.empty?
  3.times do
    @post.comments.build
 end
end
p @comments.size
=> 3

答案 1 :(得分:0)

自动保存在Post模型中定义。阅读有关自动保存的here。如果我正确理解您的问题,那么定义:autosave => false

就足够了