尝试实施 Sarah 的解决方案时,我遇到了 2 个问题:
首先,当想要通过做分配同义词时,该解决方案不起作用
word.synonyms << s1 or word.synonyms = [s1,s2]
间接删除同义词也无法正常工作。这是因为 Rails 在自动创建或删除 Link 记录时不会触发 after_save_on_create 和 after_destroy 回调。至少在我尝试过的 Rails 2.3.5 中没有。
这可以通过在 Word 模型中使用 :after_add 和 :after_remove 回调来解决:
has_many :synonyms, :through => :links,
:after_add => :after_add_synonym,
:after_remove => :after_remove_synonym
回调是莎拉的方法,稍作调整:
def after_add_synonym synonym
if find_synonym_complement(synonym).nil?
Link.new(:word => synonym, :synonym => self).save
end
end
def after_remove_synonym synonym
if complement = find_synonym_complement(synonym)
complement.destroy
end
end
protected
def find_synonym_complement synonym
Link.find(:first, :conditions => ["word_id = ? and synonym_id = ?", synonym.id, self.id])
end
The second issue of Sarah's solution is that synonyms that other words already have when linked together with a new word are not added to the new word and vice versa.
Here is a small modification that fixes this problem and ensures that all synonyms of a group are always linked to all other synonyms in that group:
def after_add_synonym synonym
for other_synonym in self.synonyms
synonym.synonyms << other_synonym if other_synonym != synonym and !synonym.synonyms.include?(other_synonym)
end
if find_synonym_complement(synonym).nil?
Link.new(:word => synonym, :synonym => self).save
end
end