2013-08-17 4 views
0

Это код:Как уменьшить этот код ruby?

def explaination_exists 
explaination_exists_flag = false 
if self.explanation1.length > 5 
    explaination_exists_flag = true 
end 
if self.explanation2.length > 5 
    explaination_exists_flag = true 
end 
if self.explanation3.length > 5 
    explaination_exists_flag = true 
end 
if self.explanation4.length > 5 
    explaination_exists_flag = true 
end 

unless explaination_exists_flag 
    errors.add(:base, 'Atleast one explanation should be there.') 
end 
end 

Я хочу, чтобы уменьшить код к одной строки кода, так как нет никаких изменений для объяснений [номер] за исключением.

Я попытался это:

def explaination_exists 
explaination_exists_flag = false 
(1..4).each do |i| 
    if self."explanation#{i}".to_sym.length > 5 
    explaination_exists_flag = true 
    break 
    end 
end 
unless explaination_exists_flag 
    errors.add(:base, 'Atleast one explanation should be there.') 
end 
end 

Я знаю, что это глупо, но вы можете предложить мне некоторые изменения, которые могли бы работать.

Спасибо!

+2

Всякий раз, когда у вас есть длинный список имен переменных, которые выглядят как var 'i'..'j'. Для хранения этой информации используются неправильные структуры данных. Пожалуйста, рефакторинг кода, который получает 'объяснение'1,2,3 .... Возможно, есть лучший способ сохранить эти переменные. Может быть в массиве? – bsd

ответ

4
def explaination_exists 
    return if (1..4).any?{|i| send("explaination#{i}").length > 5} 
    errors.add(:base, "Atleast one explanation should be there.") 
end 
+0

На самом деле я хотел проверить, ЛЮБОЙ из объяснения.length> 5. В любом случае он работал с некоторыми изменениями, спасибо! – Gaurav

+0

Я лично удаляю 'return' и меняю' if' на 'if'. – Phrogz

+0

@Phrogz Если он подходит в одной строке, поэтому я могу использовать постфиксный синтаксис, тогда я бы это сделал. – sawa

3

Вот мой быстрый удар в нем:

def explanation_exists 
    return true if [explanation1, explanation2, explanation3, explanation4].map(&:length).any? { |length| length > 5} 
    errors.add(:base, 'Atleast one explanation should be there.') 
end 
+0

еще приятнее, чем у меня :) – Amir

+0

Лучший способ, я всегда забываю что-нибудь? метод – jbh

+0

Это сообщение об ошибке, что метод 'length' не определен. В любом случае спасибо! – Gaurav

0
def explanation_exists 
    [:explanation1, :explanation2, :explanation3, :explanation4].inject(false) do |result, method| 
    result || (self.send(:method).length > 5) 
    end 
end 
0
def explaination_exists 
    return true if %w{ explanation1 explanation2 explanation3 }.map do |exp| 
       self.send("#{exp}").length > 5 
       end.detect { |e| e } 

    errors.add(:base, 'Atleast one explanation should be there.') 
end 
0

Я бы разделить это немного, что-то вроде:

def explanations 
    [explanation1, explanation2, explanation3, expanation4] 
end 

def explanation_exists 
    errors.add(:base, :explanation) unless explanations.any? { |e| e.length > 5 } 
end 

и положить сообщение об ошибке в ваш язык под activerecord.errors.models.<your-model-name>.attributes.base.explanation (IIRC).

Смежные вопросы