2016-04-15 3 views
1

Сейчас у меня есть код, который выглядит следующим образом:Более короткий код, предотвратить дублируется вызов,

def work_with_access_token_or_request_one 
    if is_valid_access_token?(params[:code]) 
     request_client_with_access_token(params[:code]) 
    else 
     request_access_token! 
    end 
end 

В этом методе я первый чек если код я получаю в Params является действительным. Если нет, прошу.

Моя проблема в том, что сейчас метод get_access_token является вызывается дважды. Однажды, когда я проверяю, является ли access_token действительным, и в другое время, когда я запрашиваю клиента.

def get_access_token(code) 
    return Okto.request_access_token_from_code(code) 
end 

Я должен сделать это, потому что выход get_access_token(code) возвращается при успешном {access_code: 89283} или если произошла ошибка {error: "not valid"}

def is_valid_access_token?(code) 
    result = get_access_token(code) 
    return result[:access_code] 
end 

def request_client_with_access_token(code) 
    result = get_access_token(code) 
    client = Okto.get_client_from_access_code(result[:acess_code]) 
end 

Как я могу переписать свой код в work_with_access_token_or_request_one так, что только один раз методом get_access_token называется? Thanks

+0

Являются ли 'code' и' get_access_token (code) 'логически эквивалентными? Если они тогда, то все, что работает с «кодом», также должно работать, если задано 'get_access_token (code)'. Затем вы можете использовать патч обезьяны в методе 'code.to_access_token', который бы вызывал' get_access_token (self) 'на код и просто« возвращал себя »при вызове маркера доступа. Затем коды могут кэшировать маркер внутри (или вызывающий может вызвать 'to_access_token'), и эти два метода просто скажут« result = code.to_access_token »и не заботятся о том, что им дано. Может быть, уродливый, если все это просто строки и хэши. –

+0

SO читатели в основном взрослые, поэтому вам не нужно смело смотреть на определенные слова и фразы. –

ответ

1

Похоже, что эти методы относятся к одному классу. Затем, вы можете переписать ваши get_access_token метод в кэш результаты так:

def get_access_token(code) 
    @access_token_cache ||= {} 
    @access_token_cache[code] ||= Okto.request_access_token_from_code(code) 
    @access_token_cache[code] 
end 

Если code должен истекать, то вы можете добавить эту логику внутри вашего метода, а также.

+0

Извините, но в этом конкретном коде я не могу использовать переменную класса. Благодарим за вас. Возможно, у вас есть другая идея? –

+0

John, '@ access_token_cache' - это переменная экземпляра, а не переменная класса. '@@ access_token_cache' - это переменная класса. –

1
def access_token(code) 
    h = get_access_token(code) 
    h.key?(:access_code) ? h[:access_code] : nil 
end 

def work_with_access_token_or_request_one 
    result = access_token(@params[:code]) 
    result ? request_client_with_access_token(result) : request_access_token! 
end 

Если вы можете изменить get_access_token и нет предосудительного побочного эффекта, вы можете упростить:

def get_access_token(code) 
    h = Okto.request_access_token_from_code(code) 
    h.key?(:access_code) ? h[:access_code] : nil 
end 

def work_with_access_token_or_request_one 
    result = get_access_token(@params[:code]) 
    result ? request_client_with_access_token(result) : request_access_token! 
end 

Обратите внимание, что переменный, указывающий на хэш должен быть переменным экземпляр (@params) для хеша чтобы быть видимым внутри метода.

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