0

Ruby on Rails 코드의 리팩터링 방법은 무엇입니까?값의 범위가있는 리팩토링 조건

def select_plan 
     unless params[:plan] && (params[:plan] == '1' || params[:plan] == '2' || params[:plan] == '3' || params[:plan] == '4' || params[:plan] == '5' || params[:plan] == '6' || params[:plan] == '7' || params[:plan] == '8') 
      flash[:notice] = "Please select a membership plan to register." 
      redirect_to root_url 
     end 
    end 
+0

유효한 계획 번호는 어디에서 비롯 되었습니까? 그들은 데이터베이스에서 왔습니까? 그 (것)들을 어딘가에 정의하는 상수가 있습니까? 코드 전체에 마술 번호가 뿌려 졌습니까? –

+0

"6은 유효한 계획"이라는 사실은 컨트롤러 메서드 나 여러 다른 장소에만 있기 때문에 리팩터링 할 필요가 있습니다. 실제로는 'select_plan'에있는 번거로운 구현이 아닙니다. 기본 문제를 해결하면'select_plan' 자체가 부작용으로 정리됩니다. –

+0

@muistooshort - 내 수준의 경험을 용서해주십시오. 유효한 플랜 번호가 데이터베이스에 있습니다. 나는 당신이해야 할 말에 관심이 있습니다. 나는 당신이 의미한다는 것을 완전히 확신하지 못합니다. –

답변

0

같은 다음 뷰에 대한 전체 플랜 세부 사항에 액세스 할 수 있으므로 이름, 설명, 가격 등을 표시 할 수 있습니다. 계획의 존재는 한 장소 (예 : 데이터베이스)에만 저장됩니다. 당신이 @plan를 필요로하지 않는 경우에 당신이 말할 수 :

if(!Plan.where(:id => params[:plan]).exists?) 
    ... 
end 

중요한 점은 정확히 하나 개의 유효한 계획이 무엇인지 알고있는 것은 당신이 계획에 대해 알아야 할 모든 시간이 있어야한다는 것입니다, 당신은 부탁드립니다 한 가지는 오직 한 가지뿐입니다.

또한 유효한 계획 얻기 위해 (대신 문자 숫자 팔을 통해 하나의) 데이터베이스를 사용하는 것이 select_plan를 호출 끝 뷰 :

<% Plan.order(...).each do |p| %> 
    whatever you need to display the plan as an option... 
<% end %> 

데이터베이스에 새로운 계획을 추가하고 모든 여전히 작동 . 계획을 제거/비활성화하면 모든 것이 여전히 작동합니다. 소프트웨어 유지 관리가 쉽고, 버그가 적으며, 이해하기 쉽고, 나쁜 소프트웨어가 아닌 새로운 좋은 습관을 얻게됩니다.

+1

시간을내어 적절한 RoR의 예를 설명하고 제공해 주셔서 감사합니다. 나는 첫 번째 해결책을 구현했다. –

3

나는 이렇게 할 것입니다. Plan 진짜 일 확인 :

def select_plan 
    unless params[:plan].in?('1'..'8') 
    flash[:notice] = "Please select a membership plan to register." 
    redirect_to root_url 
    end 
end 

또는 무 같은

제안 너무 짧습니다. 그것은 데이터베이스 모델 또는 단지 작은 루비 클래스 수 있습니다 : 이제

@plan = Plan.find_by(:id => params[:plan]) 
if([email protected]) 
    flash[:notice] = "Please select a membership plan to register." 
    redirect_to root_url 
end 

: 계획 번호가 데이터베이스에 다음 간단하게 말할 수있는 Plan 모델이있는 경우

# in app/models/plan.rb 
require 'set' 
class Plan 
    VALID_PLANS = Set.new('1'..'8').freeze 

    def self.valid_plan?(plan) 
    VALID_PLANS.include?(plan) 
    end 
end 

# used like 
def select_plan 
    unless Plan.valid_plan?(params[:plan]) 
    flash[:notice] = "Please select a membership plan to register." 
    redirect_to root_url 
    end 
end 
+0

여기 실제 문제가 빠져 있다고 생각합니다. "이'if 문을 어떻게 다시 작성해야합니까?"라는 것이 표면 문제인데, 실제 문제는 "params [: plan]이 유효한 계획인지 어떻게 알 수 있습니까"입니다. –

+0

@muistooshort, 이해가 안되네. 그것은 나에게 이것이 둘 다 같다. –

+0

@CarySwoveland : 아마도 "계획"은 응용 프로그램의 기본적인 부분이므로 컨트롤러 방법에서 몇 가지 마법의 숫자로 사용할 수있는 계획 번호를 사용하면 정말 나쁜 생각으로 받아들입니다. 유효한 계획 번호가 무엇인지 아는'Plan' 모델이 있어야합니다. 그러면 컨트롤러는'params [: plan]'이 유효하고'Plan'이 아마도 데이터베이스를 참조하는 경우'Plan'을 물어볼 것입니다. 고립 된 조각으로 코드는 괜찮지 만 애플리케이션 전체적으로 좋지 않은 냄새가납니다. –