Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

current_project helper method 만들기 #51

Open
angdev opened this issue Aug 16, 2014 · 16 comments
Open

current_project helper method 만들기 #51

angdev opened this issue Aug 16, 2014 · 16 comments

Comments

@angdev
Copy link
Member

angdev commented Aug 16, 2014

current_user 처럼 current_project 메소드가 ApplicationHelper에 있으면 좋을 것 같은데, 어떻게 생각하시나요? 이를 위해서 routes.rb에서부터 project id parameter를 project_id로 통일해주는 것이 좋을 것 같은데..

@shaynekang
Copy link
Contributor

흠... 시도해본 적 없는 거라 확신은 못 하겠네요.(..)
프로젝트가 어떤 방향으로 발전해가는지에 따라, 좋은 구현이 될지 아닐지 갈릴 것 같습니다.

그래도 한 번 시도해볼까요? ㅎㅎ

@angdev angdev self-assigned this Aug 16, 2014
@yhoonkim
Copy link
Contributor

엇 나도 이거 고민하고 있었음.
routes.rb에서 project id parameter를 project_id로 통일해주려고 시도해보려고 했는데 resource이거 쓰니까 마음대로 잘 못바꾸는 것 같음. 깔끔하게 안되넹...

현재는

  • nested되어있으면 params[project_id]
  • nested되어있지 않으면 uri가 projects/{"id}인지 검사 후 Project.find 를 하고 있습니다.

@angdev
Copy link
Member Author

angdev commented Aug 18, 2014

이거에 대한 정보를 좀 찾아봤는데, 일단 project_id로 통일할 수가 있기는 한데 이러면 convention이 깨지는 거라서 문제가 생길 수 있다고 하고, 깔끔하게 통일하는 방법 자체도 없는 것 같음.

통일이 안 된다면 ProjectsController에서는 대체적으로 id를 쓰고 있고 TodosController, HistoriesController에서는 project_id를 쓴다는 점에서 before_action 으로 @current_project를 넣어주는 방식도 생각을 해봤는데, 일단 잘못된 프로젝트 객체가 @current_project에 들어갈 수도 있고 안전하지 못하다는 점에서 current_project는 만들지 않는 것이 좋을 것 같음.

project_id를 detect할 수 있는 방법만 있으면 되는데, 이게 액션 별로 달라서 좀 힘든듯..

@shaynekang
Copy link
Contributor

으흐흐... 포기? ㅋㅋ

@angdev
Copy link
Member Author

angdev commented Aug 18, 2014

음 일단 제가 생각했던 방식은

# projects_controller.rb
before_action :retrieve_current_project

def retrieve_current_project
  project_id = params[:id]
  @current_project = Project.find_by_id(project_id)
end

# histories_controller.rb, todos_controller.rb
before_action :retrieve_current_project

def retrieve_current_project
  project_id = params[:project_id]
  @current_project = Project.find_by_id(project_id)
end

# application_helper.rb
def current_project
  @current_project
end

위와 같습니다.

@current_project는 per-request storage 같은 느낌으로 사용될 수 있구요.

before_action으로 프로젝트 밀어넣어주는 건 �메타 프로그래밍이나 include 등을 통해서 해결할 수 있을 것 같은 느낌도 들었어요. (이 컨트롤러에서는 project 객체를 사용한다라는 의미의 DSL을 도입한다는 의미로)
만약 이게 된다면 다른 리소스들도 비슷하게 넣어줄 수 있겠죠. (라이브러리처럼 쓸 수 있을 것 같네요)

# project_controller.rb
own_resource :project # own_resource는 before_action에서 id로 리소스를 가져와줌.

# histories_controller.rb
parent_resource :project # parent_resource는 before_action에서 project_id로 리소스를 가져와줌.

지금 문제가 이러한 관계가 routes에서만 정의되어 있고 컨트롤러 사이에서는 모른다는 점인 것 같습니다.
이걸 해결해주는게 위에서 제가 언급한 방법이고, devise의 helper 정의 방식 처럼 own_resource :project 같은 것과 더불어 조금의 코드를 더 첨가하여 current_{resource}를 정의를 해줄 수도 있을 것 같구요.

근데 만약 한 컨트롤러에서 project_id로써 다른 이름을 사용하는 액션이 생기는 순간 귀찮아질 것 같더라구요. :only, :except 같은 옵션이 생겨날 것 같고.. 이렇게 되면 model 파일이나 serializer 처럼 이런 정보들을 정의해주는 파일이 생겨나게 될 것 같은 느낌도 듭니다.

# project_resource_relation.rb (가칭)
class ProjectResourceRelation
  owner :project
  child :history, except_action: { name: 'blahblah', as: 'prozect_id' }
  child :todo
end

를 하면 current_project를 컨트롤러 on_load에 집어넣어 줍니다 (..)

물론 지금은 이러한 예외가 없어서 최소한의 노력으로 구현을 해볼 수 있을 것 같은 생각도 들지만 지금은 배보다 배꼽이 큰 느낌이네요. 구현한다고 하면 천천히 구현해도 될 것 같다는게 제 생각입니다.

@shaynekang
Copy link
Contributor

뭔가 엄청 복잡하네요.(..)
저도 좀 더 고민하다가, 천천히 구현한다에 한 표 걸겠습니다. ㅋ

@angdev
Copy link
Member Author

angdev commented Aug 18, 2014

정말 우연하게 이런 젬을 발견했습니다. 제 생각이랑 비슷한 것 같습니다만

https://github.com/hashrocket/decent_exposure#scoping-your-object-queries

이런 느낌으로 적용하지 않을까..

@shaynekang
Copy link
Contributor

하하하... 저 젬을 제가 한국에서 유행시킬려고 적극 밀었다가, 욕을 바가지로 먹은 적이 있죠.(..)
예제를 보면 좋아 보이지만, 실제로는 대부분의 컨트롤러가 decent_exposure로 깔끔하게 리펙토링이 되지 않습니다.(예외상황이 많아서) 결국 코드가 더 지저분해지거나, 알 수 없는 내용의 코드가 잔뜩 생기게 되죠. ㅎㄷ

@angdev
Copy link
Member Author

angdev commented Aug 18, 2014

방향은 비슷한데 역시 그런 점은 피할 수 없을 것 같네요. 비슷한데 제가 제일 마지막에 언급했던 방식으로 구현한 젬은 없는지 궁금하네요 ㅋㅋ 그렇다고 해도 이상한 코드가 잔뜩 ..

@shaynekang
Copy link
Contributor

음... 제가 알기로는 없습니다.(먼산)
하나 만드셔서 오픈 소스의 구루가 되세요! (아니면 모든 개발자들의 샌드백이 되던가 ㅋㅋ)

@shaynekang
Copy link
Contributor

@fegs @yhoonkim 요건 어떻게 할까요? 일단은 Pending?

@angdev
Copy link
Member Author

angdev commented Aug 20, 2014

일단 Pending 상태로 걸어두는 것이 좋을 것 같습니다. 그동안 제가 천천히 구현해보고 있겠습니다!

@shaynekang
Copy link
Contributor

ㅇㅋ 확인했습니다. 요런건 pending 라벨 같은걸 붙일까요?

@yhoonkim
Copy link
Contributor

네 우선은 보류하는게 좋을것 같습니다.

@angdev
Copy link
Member Author

angdev commented Aug 30, 2014

@shaynekang 멘토님 혹시 https://github.com/josevalim/inherited_resources 이거 써보셨나요?

@shaynekang
Copy link
Contributor

아니요. 하지만 많이 들어봤습니다. ㅋㅋ(José Valim 은 레일즈의 유명한 메인테이너거든요)
저는 딱 보자마자 Decent Exposure의 느낌이 들어서 사용할 마음이 없었습니다.(..)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants