2016-06-08 2 views
1

레일즈 UJS 모달이 있습니다. 사용자가 버튼을 클릭하면 아약스 호출이 트리거됩니다. 특정 데이터베이스를 업데이트하지만 레일즈 ujs/ajax가 타임 아웃을 호출하거나 오류를 출력하기를 원합니다.이 데이터베이스를 업데이트하지 마십시오.레일스 UJS (ajax)가 오류 또는 타임 아웃을 반환하는 경우 데이터베이스 작업 방지

컨트롤러에서이 작업을 수행해야한다고 생각하지만 어떻게해야합니까?

HTML

<div id="zone" class="has-js">  
     <%= link_to image_tag(smallest_src_request), 
       deal_modal_path, 
       remote: true, 
       class: "deal", 
       alt: "loadin'" %> 
     </span> 
    </div> 
    <% end %> 
</div> 

컨트롤러

def deal_modal  
    # First Find UserDeal participation and update it 
    find_and_update_selected_userdeal 
    # Actions on User 
    update_user_profile 

    respond_to do |format| 
     format.js 
    end 
end 

그래서 요청 시간 초과는, 내가 좋아하는 고전적인 메시지 '죄송합니다 너무 오래 ...'괜찮 표시하지만주의 경우 이것에도 불구하고 실제로 모든 컨트롤러 작업을 수행하고 suerdeal 및 user 테이블을 업데이트하고있었습니다.

나는 원하지 않습니다.

before 또는 after_filter를 사용하고 xhr 상태가 오류 ("timeout"의 경우를 포함한다고 생각하는 경우)라고 말한 다음 find_and_update_selected_userdeal 및 update_user_profile과 같은 deal_modal 메소드에서 이러한 모든 메소드를 수행하지 마십시오.

그럴 수 있습니까?

편집

이 문제는 데이터베이스 호출의 효율성에 관련되지 않은 일부 상황. 사실 그것은 매우 빠릅니다 (정상적인 연결은 150ms입니다).하지만 앱은 모바일 강렬하고 비즈니스 규칙이 있습니다 (특히 버튼을 클릭 한 후 나타나는 모달의 콘텐츠를 볼 수있는 횟수, 3)로 제한됩니다.

예 : 사용자가 지하철에 있습니다 (현재 인터넷에 연결되어 있음). 그는 링크를 클릭하는데, 오늘 user.total_nb_clicks (1 단위 증가)로 User 테이블을 업데이트하지만, 20 초 동안 인터넷 연결이 거의없는 터널을 입력합니다. UX 용으로 Rails UJS timeout을 10 초로 설정했습니다 (사용자가 버그라고 생각하지 않도록). 따라서 연결이 너무 느려서 Modal via Rails UJS의 메시지가 결과가 아니라 'sorry timeout, try again'과 같은 sth입니다. 그러나 그는 자신의 행운을 3 번만 시도 할 수 있도록 허용되어 있으므로 'total_shots'란을 업데이트해서는 안됩니다. 그의 잘못이나 앱의 잘못이 아니라 터널이 있었는데 인터넷 연결이 초당 5kb 밖에 없었습니다. 그는 여전히 2 개의 모달/결과를 볼 수있는 권리가 있습니다. 그것은 발생할 수있는 실제 모바일 usecase의 문제입니다 ...

+0

데이터베이스 업데이트가 너무 오래 걸리기 때문에 아약스 호출이 시간 초과된다는 주장이 들립니다. 타임 아웃이 발생했을 때 데이터베이스를 업데이트하지 않는 유일한 방법은 요청이 응용 프로그램을 처음부터 치는 것을 방지하기 위해 시간을 거슬러 올라가는 것입니다. 시간 초과 상황을 피하는 데 집중해야합니다. 업데이트가 너무 느려서 시간 제한에 처한 이유를 조사하십시오. – spickermann

+0

나는 당신의 요지를 얻는다. 내 앱은 휴대 성이 강하다. 예를 들면 : 사용자가 지하철에있다 (그리고 지금 그는 인터넷에 연결되어있다). 그는 링크를 클릭하는데, 오늘 user.total_nb_clicks (1 단위 증가)로 User 테이블을 업데이트하지만, 20 초 동안 인터넷 연결이 거의없는 터널을 입력합니다. UX 용으로 (사용자가 버그라고 생각하지 않도록) 앱을 10 초 동안 시간 초과하도록했습니다. 그러면 그가 보는 메시지는 '죄송합니다 시간 초과, 다시 시도하십시오'입니다. 하지만 그는 'total_shots'란을 업데이트하지 말아야하므로 3 번만 클릭 할 수 있습니다. 진짜 인생의 사건입니다. – Mathieu

+0

이 컨텍스트로 질문에 추가하면 질문을 이해하는 데 유용합니다. – Mathieu

답변

1

나는 비슷한 문제가 how Heroku suggests you handle timeout in its environment에서 보였습니다. 그러나 시간 초과가 장시간 실행되는 서버와 아무 관련이 없으므로 귀하의 사례 시나리오에서 작동하지 않을 것이라고 생각합니다. 사이드 프로세싱.

컨트롤러가 작업을 끝내면 클라이언트가 요청 후 응답을받지 못한 경우 http 요청이 성공했는지 여부를 알 수 없습니다. 나는 그것이 HTTP Protocol is stateless이기 때문에 그것이다고 생각한다.

다른 말로하면 시도해 볼 수 있습니다. 내가 생각할 수있는 더 간단한 방법은 다음에 사용자가 콘텐츠를 시각화하려고 시도하거나 연결이 다시 설정 될 때 동일한 데이터를 사용자에게 표시하는 지속성 정보 (새 클릭으로 계산되지 않음)입니다.

+0

감사합니다. 헤이 나는 너무 heroku 너무 heroku에 의해 유도 된 복잡성의 추가 계층을 처리하기 위해 매우 흥미로운 사용하고 있습니다 :)하지만 내 질문에 관해서는, 결국 레일 트랜잭션을 사용하지만 여전히 모든 것을 알아 내지 못했다 : 너무 내 의견을 확인하십시오 관심이 있다면 : http://stackoverflow.com/questions/37729964/rails-controller-execute-action-only-if-the-rails-ujs-method-inside-succeed – Mathieu

+0

나는 아직도 당신이 할 수 있다고 생각지 않는다. 네가 원하는대로 네가 물었던거야. 귀하의 의견에 링크 된 질문은 또한 컨트롤러 (예 : 장시간 실행중인 프로세스 또는 실패한 작업) 내에서 상황을 해결하고 느린 응답이 이미 컨트롤러에서 빠져 나온 클라이언트로 다시 중단됩니다. 하지만 문제가 해결 되었다면 배워야 겠어. 제발, 당신의 솔루션을 공유하십시오! –

+0

실제로 문제의 해결책을 찾지 못했습니다. 나는이 문제와 "좋은 해결책"을 잠시 나갈 수있는 방법을 찾았다. 따라서 첫 번째 2 가지 메소드의 경우 레일스 트랜잭션으로 래핑합니다 (하나가 작성되지 않은 경우 다른 하나가 롤백됩니다). 그러나 여전히 모달을 표시하는 thrid 메소드 (응답 format.js 파트)와 관련된 문제가 있습니다. 여기에 해결책은 없지만 돌아갈 수있는 방법이 있습니다. 데이터베이스가 업데이트되면 sidekiq에서 전자 메일을 트리거하고 사용자에게 미안한 시간 제한을 표시하지만 전자 메일로 결과를 확인하십시오. – Mathieu