Rails обновляет поле без формы

У меня есть приложение Rails 4.0 с моделью "заказ", в которой есть поле статуса. При вызове действия «показать» для получения сведений об объекте «заказ» я хочу добавить дополнительные кнопки на «Показать страницу» в дополнение к «Редактировать» и «Назад». Первая, чтобы отметить «обновить статус», который обновит статус этого объекта заказа только до «1», а вторая кнопка, чтобы отметить «закрыть заказ», который будет обновлять статус этого объекта заказа только до 2. Как я могу добиться этого без «Редактировать» действие/представление? Нужно ли использовать form_tag для добавления этих кнопок и нужно ли писать 2 новых метода в OrdersController для обновления статуса?

Ниже приведен мой show.html.erb с двумя кнопками, которые я хочу добавить...

<p>
  <strong>Name:</strong>
  <%= @order.name %>
</p>
<p>
  <strong>Status:</strong>
  <%= @order.status %>
</p>
<%= link_to 'Edit', edit_order_path(@order) %> |
<%= link_to 'Back', orders_path %> |
<%= link_to 'Shipped', '#', :name => 'shipped_button' %> |
<%= link_to 'Close',   '#', :name => 'close_button' %>

Если я нажму кнопку «Отправлено» или «Закрыть», они оба будут вызваны в «OrdersController» как запрос «GET», как показано ниже,

.. Запущен GET "/orders/1?name=shipped_button" для 127.0.0.1 21.11.2014 15:40:38 -0800
Обработка с помощью OrdersController#show as HTML
Параметры: {"name" =>"shipped_button", "id"=>"1"
Загрузка заказа (0,1 мс) ВЫБЕРИТЕ "заказы".* ИЗ "заказов" ГДЕ "заказы"."id" = ? LIMIT 1 [["id", 1]]
Обработанные заказы/show.html.erb в макетах/приложении (1,9 мс)
Выполнено 200 OK за 50 мс (Просмотры: 47,8 мс | ActiveRecord: 0,1 мс)

Как я могу обновить модель с соответствующим обновлением поля статуса. «статус» — целочисленное поле в модели «заказы».


person Atarang    schedule 21.11.2014    source источник
comment
Я не могу понять, что ты хочешь. В самом деле. Не могли бы вы объяснить это более подробно? Однако вы можете передать действия функции link_to, как описано в этом вопросе   -  person AME    schedule 22.11.2014
comment
Да, этот ответ, на который вы указали, похоже, сработает в этом случае. link_to просто вызывает действие в контроллере с идентификатором или целым объектом в качестве входного параметра.   -  person Atarang    schedule 23.11.2014


Ответы (1)


Я бы сделал это с помощью ajax:

Вам нужно что-то подобное в вашем файле routes.rb.

resources :orders

заказы/show.html.erb:

<div id="order" data-order-id="<%= @order.id %>"></div>

<p id="notice"><%= notice %></p>

<p>
  <strong>Status:</strong>
  <%= @order.status %>
</p>

<p>
  <strong>Name:</strong>
  <%= @order.name %>
</p>

<%= link_to 'Edit', edit_order_path(@order) %> |
<%= link_to 'Back', orders_path %>
<%= link_to 'Shipped', '',id: "ship" %> |
<%= link_to 'Close',   '', id: "close" %>



<script> 
$(function () {
    var orderId = $('#order').data("order-id");
    var shippButton = $('#ship');

    var closeButton = $('#close');
    alert(orderId);



    closeButton.on("click", function() {
        $.ajax({
            url: '/orders/'+orderId,
            type: 'PATCH',
            dataType: 'json',
            data: {"order": { "status": "4"}},
            complete: function (jqXHR, textStatus) {
                // callback
            },
            success: function (data, textStatus, jqXHR) {
                // inform user that it was a sucess like:
                alert("successfully changed the order to closed");
            },
            error: function (jqXHR, textStatus, errorThrown) {
                // do something if the request fails
            }
        });
    });

    shippButton.on("click", function() {
        $.ajax({
            url: '/orders/'+orderId,
            type: 'PATCH',
            dataType: 'json',
            data: {"order": { "status": "3"}},
            complete: function (jqXHR, textStatus) {
                // callback
            },  
            success: function (data, textStatus, jqXHR) {
                // inform user that it was a sucess like:
                alert("successfully changed the order to shipped");
            },  
            error: function (jqXHR, textStatus, errorThrown) {
                // do something if the request fails
            }   
        }); 
    });
});

</script>
person AME    schedule 22.11.2014
comment
@ auL5agoi, Спасибо, я попробую это изменение и обновлю свой ответ. Но поскольку я никогда раньше не занимался Javascript, куда бы я поместил эти JS-функции в show.html.erb? Они находятся под каким-то html-тегом? - person Atarang; 22.11.2014
comment
@Atarang А, хорошо, вы можете обернуть их тегом script, это все внутри вашего файла show.html.erb. обновил мой ответ. Кстати. Пожалуйста, опишите, какие атрибуты вам нужно изменить: например: статус: 1, когда x, статус: 2, когда y и так далее. - person AME; 22.11.2014
comment
@ auL5agoi, я еще не пробовал твое предложение. Я заказал модель, которая имеет СТАТУС Хеш с { :new =› 1, :open =› 2, :shipped =› 3, :close =› 4 } и в зависимости от нажатия на «отправлено» или «закрыть» мне нужно чтобы установить соответствующее значение в поле «статус» в модели. Почему ваш подход считается «плохим»? Каким был бы способ Rails добиться того же самого без кода JS? - person Atarang; 22.11.2014
comment
@Atarang Я не знаю о пути Rails - я пытаюсь решать проблемы. Не могли бы вы попробовать мой пример? - person AME; 23.11.2014
comment
@ auL5agoi, после внесения изменений в соответствии с вашим предложением я вообще не вижу вызова функции ajax. В выражении ‹%= link_to 'Shipped', '#',id: ship %›, как это вызывает функцию ajax? - person Atarang; 24.11.2014
comment
Вы установили Jquery? проверьте свой Gemfile для jquery - person AME; 24.11.2014
comment
Да, гем jquery-rails установлен. См. ниже снимок пакета: Использование railties (4.0.0) Использование coffee-rails (4.0.1) Использование похода (1.2.3) Использование jbuilder (1.5.3) Использование jquery-rails (3.1.2) Использование json (1.8.1) ) С помощью упаковщика (1.3.5) С помощью наклона (1.4.1) С помощью звездочек (2.11.3) - person Atarang; 24.11.2014
comment
@Atarang Тогда я не знаю, что здесь не так. Все, что я могу сказать, это то, что я на самом деле протестировал все вещи, и они работают. Вы создали эти продукты с помощью строительных лесов? - person AME; 24.11.2014
comment
Да, я создал их с лесами. Я отлаживаю позже сегодня вечером. Спасибо за ваше время и помощь. Кстати, эта функция ajax должна обновлять БД напрямую, должна ли она вызывать метод из «OrdersController», если да, то какой? Могу ли я указать другой метод, который вызывается и обновляет только тот статус, который мне нужен? - person Atarang; 24.11.2014
comment
@Atarang Я все отредактировал - просто скопируйте и вставьте все это на свою страницу orders/show.html.erb. Только что еще раз успешно протестировал. - person AME; 24.11.2014