Mongoid destroy方法不能与has_and_belongs_to_many关系一起使用

时间:2013-12-06 16:56:25

标签: ruby-on-rails mongodb mongoid

我正在使用Mongoid版本2.8.1。我注意到,当模型与destroy关系时,has_and_belongs_to_many方法不起作用。

例如,我有两个模型

class Article
    include Mongoid::Document
    has_and_belongs_to_many :subjects
    ...
end

class Subject
    include Mongoid::Document
    has_and_belongs_to_many :articles
    ...
end

现在我要删除一篇文章文档。所以我试过

a = Article.find('someid1234')

这会返回一个有效的对象,然后我会

>> a.destroy
=> true
>> a.errors.any?
=> false
>> a.errors.count
=> 0

但是当我做的时候

a.reload

我仍然把对象拿回来了!

如果我使用

a.delete

相反,它会工作,但delete不会运行回调,我想运行回调。

我把它钉在了has_and_belongs_to_many关系上。由于这种关系,destroy调用了一个回调方法。

Article._destroy_callbacks
=> [#<ActiveSupport::Callbacks::Callback:0x007fc4a0e71258 @klass=Shortlist, @kind=:after, @chain=[...], @per_key={:if=>[], :unless=>[]}, @options={:if=>[], :unless=>[]}, @raw_filter=#<Proc:0x007fc4a0e714d8@/opt/boxen/rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/mongoid-2.4.12/lib/mongoid/relations/synchronization.rb:160>, @filter="_callback_after_31(self)", @compiled_options="true", @callback_id=32>]

/opt/boxen/rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/mongoid-2.4.12/lib/mongoid/relations/synchronization.rb:160中的相关方法 是

def synced_destroy(metadata)
    tap do
        set_callback(
            :destroy,
            :after
        ) do |doc|
            doc.remove_inverse_keys(metadata)
        end 
    end 
end

我致电a.destroy后,会从其主题的article_ids数组字段中删除其ID。但是文章a没有被销毁。所以似乎回调正确执行,但之后对象不会被销毁。

我通过查看mongoid的源代码调试了这个问题。 destroy方法看起来像

def destroy(options = {})
    self.flagged_for_destroy = true
    run_callbacks(:destroy) do
        remove(options)    # THIS IS NOT EXECUTED!
    end.tap do
        self.flagged_for_destroy = false
    end
end

def remove(options = {})
    Operations.remove(self, options).persist
end
alias :delete :remove

评论是我的。这似乎是Mongoid的一个错误,destroy只执行回调,并且不会破坏对象本身。

但是,当没有用于销毁的回调方法时(例如,在没有的模型上) has_and_belongs_to_many关系),对象被正确销毁。奇怪

是否有人遇到过同样的问题,如果有任何解决方法。

感谢。

1 个答案:

答案 0 :(得分:0)

可能是:必须引用文章而不是文章。请记住,做Article.new不会自动给出关系。 https://rentmoola.com/表示您需要以下内容

https://pypi.example.org/

解决方法是向模态添加手动删除

class Person
  include Mongoid::Document
  embeds_many :addresses
end

person.addresses = [ address ]