Rails - 功能 - 可重复使用的代码块 - 如何? - 重构

时间:2015-05-05 12:21:44

标签: ruby-on-rails ruby function refactoring codeblocks

我编写了自己编写的代码,我需要将其重写为短块。我有8个模型,我正在创建一个相关的ID表。所以我运行一段相同的代码,除了对于每个模型/对象实例,有7件事要处理。所以这就像是8个选择1中的一个循环,与其他7做同样的事情。然后从7个接下来拾取并继续。我不知道该怎么称呼这个任务 - 重构,功能等。这是网络编程新手3个月,需要一些帮助。我知道它可以完成,就像我8年前编程的那样。下面的代码块。 模型是(故事,道德,价值观,书籍,关键字,字符) 这段代码一次一个地重复所有的事情。所以我想要做的只是简单地将一个单词传递给函数,它不仅应该将其用作参数,还应该使用它来生成代码。在下面的例子中我想传递MORAL,其余的代码应该自己生成。

moral_ids_to_delete = A(@tale_relation.moral_ids) - @moral_ids

  moral_ids_to_delete.each do |id|
       moral = TaleRelation.find_by(field: 'moral_ids', moral_ids: id)
      @value_relations.each do |relation|
       if A(moral.tale_ids) - A(relation.tale_ids) == [] then
         moral.value_ids = S(A(moral.value_ids) -        A(@tale_relation.value_ids) + A(relation.value_ids))
       else
         relation.moral_ids = S(A(relation.moral_ids) - A(id))
       end
  end
  @book_relations.each do |relation|
    if A(moral.tale_ids) - A(relation.tale_ids) == [] then
      moral.book_ids = S(A(moral.book_ids) - A(@tale_relation.book_ids) + A(relation.book_ids))
    else
      relation.moral_ids = S(A(relation.moral_ids) - A(id))
    end
  end
  @keyword_relations.each do |relation|
    if A(moral.tale_ids) - A(relation.tale_ids)  == [] then
      moral.keyword_ids = S(A(moral.keyword_ids) - A(@tale_relation.keyword_ids) + A(relation.keyword_ids))
    else
      relation.moral_ids = S(A(relation.moral_ids) - A(id))
    end
  end
  @character_relations.each do |relation|
    if A(moral.tale_ids) - A(relation.tale_ids) == [] then
      moral.character_ids = S(A(moral.character_ids) - A(@tale_relation.character_ids) + A(relation.character_ids))
    else
      relation.moral_ids = S(A(relation.moral_ids) - A(id))
    end
  end
  moral.tale_ids = S(A(moral.tale_ids) - @tale_ids)
  moral.update(tale_ids: moral.tale_ids, value_ids: moral.value_ids, book_ids: moral.book_ids, keyword_ids: moral.keyword_ids, character_ids: moral.character_ids)
end

1 个答案:

答案 0 :(得分:0)

嗯,乍看起来我觉得这是一个简单的提取方法"转型。如果您有rubymine,您可以以交互方式进行。但后来我发现_ids方法发生了变化,所以我们将其作为一个额外参数添加,并调用它我们就这样做了

moral.send(:character_ids)

相当于moral.character_ids

所以我们定义了一个函数(我不知道你的代码是做什么的,SA?所以你应该选择一个更明智的函数名称)

def update_ids_or_relation(id, moral, relation, association)
  if A(moral.tale_ids) - A(relation.tale_ids) == [] then
    moral.send(association) = 
      S( A(moral.send(association)) - A(@tale_relation.send(association)) + A(relation.send(association)) )
  else
    relation.moral_ids = S(A(relation.moral_ids) - A(id))
  end
end

为了便于阅读,可能会对其进行重构,但如果您知道代码应该做什么,则更容易选择有意义的名称。所以我就这样离开了。

然后你的代码就变成了

moral_ids_to_delete = A(@tale_relation.moral_ids) - @moral_ids

moral_ids_to_delete.each do |id|
  moral = TaleRelation.find_by(field: 'moral_ids', moral_ids: id)

  @value_relations.each do |relation|
    update_ids_or_relation(id, moral, relation, :value_ids)
  end 
  @book_relations.each do |relation|
    update_ids_or_relation(id, moral, relation, :book_ids)
  end
  @keyword_relations.each do |relation|
    update_ids_or_relation(id, moral, relation, :keyword_ids)
  end
  @character_relations.each do |relation|
    update_ids_or_relation(id, moral, relation, :character_ids)
  end

  moral.tale_ids = S(A(moral.tale_ids) - @tale_ids)
  moral.save
end

我也简化了最后一行:因为值都设置正确,我们可以保存moral