2015-05-05 4 views
2

Я написал код, который написал сам, что мне нужно переписать как короткий блок. У меня есть 8 моделей, и я создаю таблицу связанных идентификаторов. Поэтому я просматриваю кусок кода, который является тем же, за исключением того, что для каждого экземпляра модели/объекта есть 7 вещей, с которыми нужно работать. Таким образом, это похоже на цикл из 8 выберите 1, сделайте что-то подобное с другим 7. затем выберите следующий из семи и продолжите. Я понятия не имею, как назвать это задание - рефакторинг, функции и т. Д. Являюсь новым для веб-программирования 3 месяца и нуждаюсь в некоторой помощи. Я знаю, что это можно сделать, поскольку я использовал программу 8 лет назад. Кодовые блоки ниже. Модели (сказки, нравственность, ценности, книги, ключевые слова, символы) этот фрагмент кода повторяется для всех вещей по одному. Поэтому я хочу просто передать слово функции и не только использовать это как параметр, но и использовать его для генерации кода. Например, в приведенном ниже примере я хочу передать MORAL, а остальная часть кода должна быть сгенерирована сама по себе.Rails - Функция - Многоразовый блок кода - Как? - рефакторинг

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 
+0

Вы должны рассмотреть вопрос о размещении этого вопроса на http://codereview.stackexchange.com/ – max

ответ

0

Ух, на первый взгляд, я думал, что это был простой метод «Извлечения метода». Если у вас есть рубин, вы можете сделать это в интерактивном режиме. Но потом я увидел, что метод _ids изменился, поэтому мы добавим, что в качестве дополнительного параметра, и назвать его мы просто делаем

moral.send(:character_ids) 

что эквивалентно moral.character_ids.

Таким образом, мы определяем функцию (я понятия не имею, что ваш код делает, S? A? Так что вы должны выбрать имя-функции более разумным)

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.

+0

Я искал метод, подобный .send() - Спасибо Следующий бит теперь - если в куске блока кода у меня есть часть строка повторяется много раз, скажем, как @ нравственности, @ моральных_помощи, .moral_ids, @ moral_relations, 'moral_ids' есть способ, которым я могу написать код, который я передаю блоку кода простым «нравственным», и он заменяет его во всех местах. Я в основном создаю код. –

+0

Используя 'send', вы просто отправляете имя метода в объект. Таким образом, вы можете просто построить интерполяцию, чтобы построить имя метода. Поэтому напишите что-нибудь вроде 'a.send (" # {part_name} _ids ")'. – nathanvda