: метод destroy не работает в приложении Rails 3.1.0 rc2? - PullRequest
2 голосов
/ 19 июня 2011

Я работаю через Agile Web Development с Rails, и мой метод: destroy из products_controller просто переводит меня на страницу демонстрации продукта.Я столкнулся с этой проблемой в другом приложении пару недель назад в приложении Rails 3.0.В этом случае мне пришлось отредактировать javascript, так что я думаю, что это может сработать и здесь.

Вот мой javascript_link_tag из моего файла application.html.erb:

<%= javascript_include_tag :defaults %>
<%= csrf_meta_tags %>

Вот метод: destroy от моего контроллера:

def destroy
  @product = Product.find(params[:id])
  @product.destroy

respond_to do |format|
  format.html { redirect_to products_url }
  format.json { head :ok }

У меня естьjquery gem установлен, и jquery - библиотека по умолчанию с Rails 3.1, так что, может быть, я ошибаюсь, почему это не работает?Любая помощь очень ценится.Спасибо!

Ответы [ 5 ]

7 голосов
/ 19 июня 2011

Если вы не используете javascript, действие: delete просто приведет вас к этому конкретному сообщению.

Если вы хотите удалить запись, используйте

<%= button_to "destroy", post, :method => :delete %>    

вместо

<%= link_to "destroy", post, :method => :delete %>     

Вот как вы можете заставить работать javascript (хотя убедитесь, что jquery загружается).

Загрузите rails.js из моего репозитория ниже после вашего кода jquery.

Взгляните на следующие файлы из моего репозитория на https://github.com/imjp/bluh

app/assets/javascripts/rails.js
app/assets/javascripts/app.js
app/views/posts/index.html    look for the delete button at the bottom
app/views/controllers/posts_controller.rb   look for the destroy action

Код теперь должен заставить вашу ссылку уничтожения работать через ajax.

2 голосов
/ 19 июня 2011

Это потому, что вы не включили правильные файлы js или не указали метод удаления. Похоже, вы все правильно сделали:

app/views/layouts/application.html.erb

<%= stylesheet_link_tag :all %>
<%= javascript_include_tag :defaults %>
<%= csrf_meta_tag %>

Метод delete не работает из-за того, что rails 3 нуждается в информации из метатега csrf, который генерируется файлами javascript из :defaults

Тогда в вашем методе link_to убедитесь, что вы включили это:

<%= link_to "destroy", post, :method => :delete %>
1 голос
/ 14 ноября 2011

Возможно, вы удалили файл rails.js, файл, содержащий код javascript, который считывает атрибут data-method в вашей ссылке, созданной методом link_to, и измените глагол запроса (get, post, put, delete).У меня была точно такая же проблема, потому что я загружал jquery.js только через javascript_include_tag.

Если это так, убедитесь, что у вас есть rails.js, и это должно решить проблему!

1 голос
/ 19 июня 2011

Я столкнулся с той же проблемой ...

Проверьте мой ответ по этому вопросу Удалить / уничтожить не работает в рельсах 3 с Jquery

Если вы используете Jqueryне прототип, тогда вам нужно добавлять Jquery.rails.js в ваш проект, иначе каждый раз, когда вы пытаетесь удалить что-либо, потребуется, чтобы показать страницу.

Я не помню, откуда я получил решение и этот Jquery.railsфайл .jsНо точно из надежного источника.

Вот код этого файла.Может быть, поможет кому-нибудь.

jQuery(function ($) {
    var csrf_token = $('meta[name=csrf-token]').attr('content'),
        csrf_param = $('meta[name=csrf-param]').attr('content');

    $.fn.extend({
        /**
         * Triggers a custom event on an element and returns the event result
         * this is used to get around not being able to ensure callbacks are placed
         * at the end of the chain.
         *
         * TODO: deprecate with jQuery 1.4.2 release, in favor of subscribing to our
         *       own events and placing ourselves at the end of the chain.
         */
        triggerAndReturn: function (name, data) {
            var event = new $.Event(name);
            this.trigger(event, data);

            return event.result !== false;
        },

        /**
         * Handles execution of remote calls firing overridable events along the way
         */
        callRemote: function () {
            var el      = this,
                data    = el.is('form') ? el.serializeArray() : [],
                method  = el.attr('method') || el.attr('data-method') || 'GET',
                url     = el.attr('action') || el.attr('href');

            if (url === undefined) {
              throw "No URL specified for remote call (action or href must be present).";
            } else {
                if (el.triggerAndReturn('ajax:before')) {
                    $.ajax({
                        url: url,
                        data: data,
                        dataType: 'script',
                        type: method.toUpperCase(),
                        beforeSend: function (xhr) {
                            el.trigger('ajax:loading', xhr);
                        },
                        success: function (data, status, xhr) {
                            el.trigger('ajax:success', [data, status, xhr]);
                        },
                        complete: function (xhr) {
                            el.trigger('ajax:complete', xhr);
                        },
                        error: function (xhr, status, error) {
                            el.trigger('ajax:failure', [xhr, status, error]);
                        }
                    });
                }

                el.trigger('ajax:after');
            }
        }
    });

    /**
     *  confirmation handler
     */
    $('a[data-confirm],input[data-confirm]').live('click', function () {
        var el = $(this);
        if (el.triggerAndReturn('confirm')) {
            if (!confirm(el.attr('data-confirm'))) {
                return false;
            }
        }
    });


    /**
     * remote handlers
     */
    $('form[data-remote]').live('submit', function (e) {
        $(this).callRemote();
        e.preventDefault();
    });
    $('a[data-remote],input[data-remote]').live('click', function (e) {
        $(this).callRemote();
        e.preventDefault();
    });

    $('a[data-method]:not([data-remote])').live('click', function (e){
        var link = $(this),
            href = link.attr('href'),
            method = link.attr('data-method'),
            form = $('<form method="post" action="'+href+'">'),
            metadata_input = '<input name="_method" value="'+method+'" type="hidden" />';

        if (csrf_param != null && csrf_token != null) {
          metadata_input += '<input name="'+csrf_param+'" value="'+csrf_token+'" type="hidden" />';
        }

        form.hide()
            .append(metadata_input)
            .appendTo('body');

        e.preventDefault();
        form.submit();
    });

    /**
     * disable-with handlers
     */
    var disable_with_input_selector = 'input[data-disable-with]';
    var disable_with_form_selector = 'form[data-remote]:has(' + disable_with_input_selector + ')';

    $(disable_with_form_selector).live('ajax:before', function () {
        $(this).find(disable_with_input_selector).each(function () {
            var input = $(this);
            input.data('enable-with', input.val())
                 .attr('value', input.attr('data-disable-with'))
                 .attr('disabled', 'disabled');
        });
    });

    $(disable_with_form_selector).live('ajax:after', function () {
        $(this).find(disable_with_input_selector).each(function () {
            var input = $(this);
            input.removeAttr('disabled')
                 .val(input.data('enable-with'));
        });
    });
});
0 голосов
/ 13 января 2012

Agile Web Development предлагает изменить файл application.html.erb по умолчанию с:

<%= stylesheet_link_tag "application" %>
<%= javascript_include_tag "application" %>

на

<%= stylesheet_link_tag :all %>
<%= javascript_include_tag :defaults %>

Оставьте по умолчанию рельсы, и он должен работать нормально.

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