基于嵌套对象存在修改has-many中的关联

时间:2013-12-15 07:04:33

标签: ruby-on-rails activerecord ruby-on-rails-4

我一直在努力解决问题的最佳方法。 我有一个很多的模型,其中列表包含许多单词,单词可以在许多列表中。 关联表是Lists_word。

我正在使用accepts_nested_attributes_for:Words

这些单词通过列表控制器作为嵌套属性提交。

我想要实现的逻辑是:

  • 如果用户修改了一个单词,我不希望该单词发生变化 引用该单词的其他列表。
  • 如果用户修改了一个单词并且它是一个新单词,则创建一个单词并将其与用户列表相关联。
  • 如果用户修改了某个单词并且该单词存在,则更改该关联。
  • 如果用户添加了单词,并且单词已经存在,则只需添加 关联。
  • 如果用户添加单词并且不存在则添加单词 到集合。

为了实现这一点,我在Lists模型中编写了一个create_or_associate模块。这很有效,但我有一种强烈的感觉,那就是有更好的方法。

def create_or_associate
# For each word submitted
self.words.each do |the_list|
  if the_list.word_changed? #(New and Changed)

    if the_list.id.nil? #new list word
      if Word.exists?(word: the_list.word)
        self.words << Word.where(word: the_list.word)
      else
        #new list word not in DB
        self.words << the_list
      end
    else
      # a changed list word
      if Word.exists?(word: the_list.word)
        # changed word already in DB
        self.words << Word.where(word: the_list.word)
        self.words.find(the_list.id).delete
      else
        #changed word not in DB
        new_word=Word.create(word: the_list.word)
        self.words << new_word
        self.words.find(the_list.id).delete
      end
    end
  end
end
end

在我的旅行中,我没有看到任何类似的代码,这些代码响起警钟,也许我不是在正确的轨道上。

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

我可能会使用这种方法

words = params[:some_word_list]
@list = List.new  #  List.find()  if you're updating
@list.words = [] if @list.persisted?
words.each do |w|
  word = Word.find_or_create_by(:word => w)
  @list.words << word
end
@list.save

希望有所帮助