Как явно вызвать действие, используемое формой в Rails 5.2? - PullRequest
1 голос
/ 21 октября 2019

Мое приложение содержит форму, позволяющую пользователю выбирать объект Playground для работы. Выбор игровой площадки обновляет поле current_playground_id текущего пользователя. Основные элементы:

rout.rb

  resources :users, :only=>[:new, :create, :edit, :update, :show, :index, :set_playground, :pass, :destroy] do
    member do
      patch :set_playground
      get :pass
    end
  end

_header.html.erb

      <% if user_signed_in? %>
        <!-- playground selection form -->
        <%= form_for(current_user, url: set_playground_user_path(current_user), method: :patch) do |f| %>
          <ul>
            <li><%= t('Playground') %>: <%= f.collection_select :current_playground_id, list_of_playgrounds, :id, :code  %> </li>
            <li class="actions" ><%= f.submit "OK" %></li>
          </ul>
        <% end %>
      <% end %>

users_controller.rb

  def set_playground
    @user.updated_by = current_login
    respond_to do |format|
      if @user.update_attributes(user_params)
        format.html { redirect_to root_path, notice: 'User switched playground.' }
       else
        format.html { redirect_to root_path, alert: 'Unable to switch playground.' }
      end
    end
  end

Я хочу вызвать то же действие set_playground из индексного представления игровых площадок, чтобы пользователь мог выбрать с этой точки игровую площадку, с которой он хочет работать. Я добавил вызов button_to в индексном представлении игровых площадок:

<code><div class="row">
  <div class="col-md-6">
    <table class="table table-striped">    
    <% @playgrounds.each do |object| %>
      <tr>
        <td class="col_narrow"> <%= image_tag object.logo if object.logo.attached? %> </td>
        <td class="col_narrow"> <%= link_to object.hierarchy, object %> </td>
        <td class="col_narrow"> 
          <%= object.translated_name %> 
          <%= button_to 'Select', [current_user, set_playground_user_path, object.id], method: :patch) %>  
        </td>
        <td class="col_wide"> <pre> <%= object.translated_description %> 
<% end%>

Я пробовал несколько синтаксисовоснованный на полиморфных методах urls или прямом вызове действия, но не смог найти правильный синтаксис для выполнения метода set_playground без генерации ошибки. В приведенном выше примере возвращается:

Не найдено ни одного маршрута {: action => "set_playground",: controller => "users"}, пропущены необходимые ключи: [: id]

Буду рад предложить решение для достижения этой цели! Большое спасибо!

Ответы [ 4 ]

0 голосов
/ 21 октября 2019

В вашем заголовке есть рабочий код, так что вы, вероятно, могли бы легче адаптировать его для отправки определенной опции. Проблема с button_to заключается в подготовке данных формы (что, очевидно, форма делает автоматически). Но, конечно, это возможно. Итак, два варианта:

Использовать фиксированную форму

<code><div class="row">
  <div class="col-md-6">
    <table class="table table-striped">    
    <% @playgrounds.each do |playground| %>
      <tr>
        <td class="col_narrow"> <%= image_tag playground.logo if playground.logo.attached? %> </td>
        <td class="col_narrow"> <%= link_to playground.hierarchy, playground %> </td>
        <td class="col_narrow"> 
          <%= playground.translated_name %>
          <%= form_for(current_user, url: set_playground_user_path(current_user), method: :patch) do |f| %>
            <%= f.hidden_field :current_playground_id, value: playground.id %>  
            <%= f.submit "Select" %>
          <% end %> 
        </td>
        <td class="col_wide"> <pre> <%= playground.translated_description %> 
<% end%>

Сборкаданные формы внутри кнопки для

Если вы хотите использовать кнопку для, вам необходимо отправить правильные данные вместе:

<%= button_to 'Select', [:set_playground, current_user], method: :patch, params: {user: { current_playground_id: playground.id }}) %> 

(обратите внимание, что [:set_playground, current_user]идентичен set_playground_user_path(current_user), поэтому вы можете переключать их, если хотите)

Также обратите внимание, что в обоих примерах я заменяю вашу переменную object на более значимую playground.

0 голосов
/ 21 октября 2019

Вы должны отправить идентификатор пользователя в функцию set_playground_user. И если я понимаю ваш код, вы также должны отправить current_playground_id. Может быть, вы можете попробовать что-то вроде:

<%= button_to 'Select', set_playground_user_path(id: current_user, current_playground_id: object.id), method: :patch) %>
0 голосов
/ 21 октября 2019

Сгенерированный маршрут:

/users/:id/set_playground

Как видите, единственный динамический сегмент - это идентификатор пользователя. Если вы хотите передать идентификатор игровой площадки, вам нужно сделать это в теле запроса.

Чтобы связать это нестандартное действие с помощниками по полиморфному маршруту, которые вы хотите использовать [:set_playground, @user], но вам также нужно установить параметр в теле:

<%= button_to 'Select', [:set_playground, @user], method: :patch, params: { current_playground_id: object.id }) %> 

Это добавляетскрытый ввод в форму.

См .:

0 голосов
/ 21 октября 2019

set_playground - это путь к члену, а не путь к коллекции, поэтому для него требуется идентификатор пользователя, поэтому правильный вызов этого метода -

set_playground_user_path(current_user)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...