2011-05-10 3 views
2

나는 여러 가지 방법을 사용하여 컨트롤러를 구축하고 있습니다. (색인, 편집, 표시 등 외에). 대개의 경우 액션은 이 단순한 GET 작업 인 것처럼 처럼 표시 될 수 있지만 어느 한 컨트롤러 동작에 너무 많은 로직을 넣고 싶지는 않습니다. 여기컨트롤러 모범 사례 : 여러 메서드 또는 여러 사례가 표시

같은 일을 달성하기 위해 두 가지 방법의 빠른 예입니다 ...

class TwitterFriendController < ApplicationController 
    ## lump everything into show? 
    def show 
    if params[:id] == "follow" 
     users = current_user.following 
    elsif params[:id] == "follow_me" 
     users = current_user.users_who_follow_me 
    elsif params[:id] == "following_follow_me" 
     users = current_user.following_who_follow_me 
    elsif params[:id] == "following_who_do_not_follow_me" 
     users = current_user.following_who_do_not_follow_me 
    ... 
    end 
    respond_with do |format| 
     format.json do {...} 
    end 
    end 

    ## or split everything out into separate methods, this requires 
additional routing 
    def following 
    ... 
    end 

    def users_who_follow_me 
    ... 
    end 

    def following_who_follow_me 
    ... 
    end 

    def following_who_do_not_follow_me 
    ... 
    end 
end 

모든
  • 하나의 방법
  • DRY의 논리 톤 쇼

에서? 추가 코드의 # 많은 라우팅 로직
  • 이하에 필요한
  • 별도의 방법

    라우팅
    • 하지 DRY
    • 쉬운 방법 조회
    • 각각의 방법
    • 을 쉽게 읽을 수

    그럼 다시 진짜 질문입니다. 그 중 어떤 기술이 보다 적습니다. 불량입니다.

    답변

    6

    내가 좋아하는 일을 할 것입니다 :

    FOLLOW_WHITELIST = %w[ follow follow_me following_follow_me following_who_follow_me following_who_do_not_follow_me ] 
    
    def show 
        if FOLLOW_WHITELIST.include? params[:id] 
         users = current_user.send params[:id].to_sym 
        end 
        respond_with do |format| 
         format.json do {...} 
        end 
    end 
    

    이 전달 매개 변수 무엇이든지 메서드를 호출합니다 [: ID] 한이 화이트리스트에있어로, (임의의 코드가 주입을 방지하기 위해).

    별도의 경로를 갖는 것은 당신에게 플러스 (더 좋은 URL을?), 당신은 또한 동적으로이 같은 뭔가 방법과 경로 생성 할 수 있었다면 :

    class TwitterFriendController < ApplicationController 
    
        FOLLOW_ACTIONS = %w[ follow follow_me following_follow_me following_who_follow_me following_who_do_not_follow_me ] 
    
        FOLLOW_ACTIONS.each do |action| 
         define_method action do 
          users = current_user.send action.to_sym 
          respond_with do |format| 
           format.json do {...} 
          end 
         end 
        end 
    
    end 
    

    을 그리고 routes.rb에서 :

    FOLLOW_ACTIONS.each do |action| 
        match action.to_sym => "controller##{action}" 
    end 
    
    +0

    아름다운 해결책 – bruno077

    +0

    매우 우아합니다. 그러나 그러한 메소드 중 하나가 모델에 삽입 할 수 없거나 삽입 할 수없는 추가 로직을 필요로하면 곧 모든 이득을 잃게됩니다. 또한 지금까지는 프로덕션 컴퓨터의 컨트롤러 메서드에서 define_method를 수행하지 않았지만 정의 할 때 모든 로컬 변수를 유지하고 (약간) 더 많은 메모리를 사용합니다. 다른 사람의 생각이 있다면 공식적인 "대답"을 선언하기 전에 듣고 싶습니다. – Schneems

    +0

    나는 다른 종류의 해결책을 기다리고 있습니다. 이러한 방법 중 하나에 추가 로직이 필요하면 더 이상 다른 방법을 사용하는 "DRY"원칙에 위배되지 않습니다. –

    관련 문제