[ruby-on-rails] Rails에서 동일한 양식에 대해 여러 제출 버튼을 생성하려면 어떻게해야합니까?

제출 버튼이 여러 개 필요합니다.

Contact_Call 인스턴스를 만드는 양식이 있습니다.

버튼 하나로 정상적으로 생성됩니다.

다른 버튼은이를 생성하지만 기본값과 다른 : attribute 값을 가져야하며 컨트롤러에서 사용되는 다르지만 관련 모델에 속성을 설정해야합니다.

어떻게하나요? 경로를 변경할 수 없는데 [: params]에 의해 선택되는 다른 변수를 보내는 방법이 있습니까?

그렇다면 컨트롤러에서 무엇을해야합니까? case 문을 설정해야합니다.



답변

여러 제출 버튼을 만들고 각각에 다른 값을 제공 할 수 있습니다.

<% form_for(something) do |f| %>
    ..
    <%= f.submit 'A' %>
    <%= f.submit 'B' %>
    ..
<% end %>

그러면 다음이 출력됩니다.

<input type="submit" value="A" id=".." name="commit" />
<input type="submit" value="B" id=".." name="commit" />

컨트롤러 내에서 제출 된 버튼의 값은 매개 변수로 식별됩니다 commit. 필요한 처리를 수행하려면 값을 확인하십시오.

def <controller action>
    if params[:commit] == 'A'
        # A was pressed 
    elsif params[:commit] == 'B'
        # B was pressed
    end
end

그러나 이것은 그다지 바람직하지 않을 수있는 컨트롤러와 당신의 관점을 밀접하게 결합 시킨다는 것을 기억하십시오.


답변

제출 버튼의 formaction 속성을 사용하는 또 다른 방법이 있습니다.

<% form_for(something) do |f| %>
    ...
    <%= f.submit "Create" %>
    <%= f.submit "Special Action", formaction: special_action_path %>
<% end %>

표준 생성 버튼은 변경이 필요하지 않으므로 코드는 깔끔하게 유지되며 특수 버튼에 대한 라우팅 경로 만 삽입하면됩니다.

formaction :
제출 버튼 또는 이미지 인 경우 입력 요소에서 제출 한 정보를 처리하는 프로그램의 URI입니다. 지정된 경우 요소 양식 소유자의 작업 속성을 재정의합니다 . 출처 : MDN


답변

또는 속성 이름을 변경하여 눌러 진 버튼을 인식 할 수 있습니다.

<% form_for(something) do |f| %>
    ..
    <%= f.submit 'A', name: 'a_button' %>
    <%= f.submit 'B', name: 'b_button' %>
    ..
<% end %>

당신이 PARAMS 키의 존재를 확인하는 대신 단순히의 확인해야하기 때문에 조금 불편 params[:commit]값을 : 당신은받을 것이다 params[:a_button]또는 params[:b_button]에 따라 하나를 눌렀습니다.


답변

보석을 사용하지 않고 @ vss123이 제안한 것과 유사한 솔루션 :

resources :plan do
  post :save, constraints: lambda {|req| req.params.key?(:propose)}, action: :propose
  post :save, constraints: lambda {|req| req.params.key?(:finalize)}, action: :finalize
end

제출 버튼 값은 종종 국제화 / 번역되므로 값 사용을 피하고 대신 입력 이름을 사용합니다. 또한 경로 파일을 빠르게 복잡하게 만들 수 있으므로 너무 많이 사용하지 않습니다.


답변

레일에서 고급 제약 조건 을 사용하여 해결했습니다 .

아이디어는 동일한 경로 (따라서 동일한 이름의 경로 및 작업)를 가지지 만 제약 조건이 다른 작업으로 라우팅되는 것입니다.

resources :plan do
  post :save, constraints: CommitParamRouting.new("Propose"), action: :propose
  post :save, constraints: CommitParamRouting.new("Finalize"), action: :finalize
end

CommitParamRoutingmatches?commit param이 주어진 인스턴스 attr과 일치하면 true를 반환 하는 메서드가있는 간단한 클래스입니다 . 값.

이것은 gem commit_param_matching 으로 사용할 수 있습니다 .


답변

오래된 질문이지만 같은 상황을 다루기 때문에 솔루션을 게시 할 것이라고 생각했습니다. 컨트롤러 로직과보기 버튼 사이에 불일치가 발생하지 않도록 컨트롤러 상수를 사용하고 있습니다.

class SearchController < ApplicationController
  SEARCH_TYPES = {
    :searchABC => "Search ABCs",
    :search123 => "Search 123s"
  }

  def search
    [...]
    if params[:commit] == SEARCH_TYPES[:searchABC]
      [...]
    elsif params[:commit] == SEARCH_TYPES[:search123]
      [...]
    else
      flash[:error] = "Search type not found!"]
      [...]
    end
  end
  [...]
end

그리고보기에서 :

<% form_for(something) do |f| %>
    [...]
    <%= f.submit SearchController::SEARCH_TYPES[:searchABC] %>
    <%= f.submit SearchController::SEARCH_TYPES[:search123] %>
    [...]
<% end %>

이런 식으로 텍스트는 컨트롤러에서 상수로 한곳에 만 있습니다. 그러나 나는 이것을 i18n하는 방법을 아직 알아 내지 못했습니다.


답변

nested_form_fields 덕분에 양식에 다양한 수의 제출 버튼이 있으므로 이름을 사용하는 것만으로는 충분하지 않았습니다. 양식에 숨겨진 입력 필드를 포함하고 양식 제출 버튼 중 하나를 눌렀을 때 Javascript를 사용하여 채웠습니다.