【问题标题】:No route matches for delete form when I set url. Other solutions, cause other problems设置 url 时删除表单没有路由匹配。其他解决方案,导致其他问题
【发布时间】:2013-07-19 18:08:23
【问题描述】:

我在用户之间有一个自引用的连接关系,它使用如下所示的友谊连接表:

用户>友谊>用户(重命名的朋友)

在我的索引页面中,我希望有一个包含两个隐藏表单的按钮,用于根据关系状态在每个用户旁边创建和销毁,以便成为好友或解除好友。我的创建关系工作正常,但对于销毁我遇到了一些问题。现在我正在处理 4 种可能性,每一种都有自己的问题。

jquery

$(document).ready(function() {
    $("li.friend-button").on('click', function(event) {
        $(this).toggleClass('button-friended friend-button');
        $(this).find("form.friend-form:hidden").submit();
    });

    $("li.button-friended").on('click', function(event) {
        $(this).toggleClass('button-friended friend-button');
        $(this).find("form.unfriend:hidden").submit();
    });
});

再培训局

<li class="<%= friended ? "button-friended" : "friend-button" %>">Friend
<!-- From UsersController: @friendship = Friendship.new -->
<%= form_for [user, @friendship], :remote => true, html: { :class => 'friend-form'}  do |f| %>
<%= f.submit %> #This creates fine
<% end %>

选项 1:

<% friendship = current_user.friendships.find_by_friend_id(user.id)%>
<%= form_for friendship, :method => :delete, :remote => true, html: {class: "unfriend"} do |f| %>
<%= f.submit %> # Works as long as all users are friended, otherwise has error: undefined method `model_name' for NilClass:Class. Since the friendship is nil.
<% end %>

控制器

def destroy
@friendship = Friendship.find(params[:id])
@friendship.destroy

选项 2

<%= form_for user, :method => :delete, :url => friendship_path, :remote => true, html: {class: "unfriend"} do |f| %>
<%= f.submit %> # Error: No route matches {:action=>"destroy", :controller=>"friendships"}. Since it's form_for user, but heading to the FrendshipsController (I guess)
<% end %>

是的,我已经看到了:一个长期存在的错误阻止 form_for 自动处理单一资源。作为一种解决方法,直接指定表单的 URL,如下所示: form_for @geocoder, url: geocoder_path do |f|

来自边缘指南

控制器

def destroy
@friendship = current_user.friendships.find_by_friend_id(params[:id])
@friendship.destroy

选项 3

<%= form_for [user, @friendship], :url => user_friendship_path, :remote => true, html: {class: "unfriend"} do |f| %>
<%= f.submit %> #Also: No route matches {:action=>"destroy", :controller=>"friendships"}, but no idea why
<% end %>

控制器

def destroy
@friendship = current_user.friendships.find_by_friend_id(params[:user_id])
@friendship.destroy

选项 4

<%= form_for [user, @friendship], :method => :delete, :remote => true, html: {class: "unfriend"} do |f| %>
<%= f.submit %>
<% end %> #Page finally renders, but get this from the dev.log:

Started DELETE "/users/4/friendships" for 127.0.0.1 at 2013-07-19 13:56:01 -0400
ActionController::RoutingError (No route matches [DELETE] "/users/4/friendships"):

控制器同O3

相关路线:

user_friendships POST   /users/:user_id/friendships(.:format) friendships#create
user_friendship DELETE /users/:user_id/friendships/:id(.:format) friendships#destroy
friendship DELETE /friendships/:id(.:format)            friendships#destroy

谢谢,提前。

【问题讨论】:

    标签: ruby-on-rails forms routing


    【解决方案1】:

    对于遇到类似问题的任何人(尽管根据我所做的研究,你们中的很多人似乎并不多)。

    所以,我能想到的最好的方法是一个非常糟糕的 hack,但它可以完成工作。在命令行上我创建了一个“假友谊”

     => #<Friendship id: 51, created_at: "2013-07-20 13:04:28", updated_at: "2013-07-20 13:04:28", user_id: 0, friend_id: 0> 
    

    虽然它不一定是假的,但我只是想用id 来解决这个问题:

    ActionController::RoutingError (没有路由匹配 [DELETE] "/users/8/friendships")

    我从上面的选项 4 中得到的。

    所以,这里是代码:

    用户控制器:

    def index
        @users = User.all
        @friendship = Friendship.new
        @friends = current_user.friends.order('id')
        # gives me a "friendship" to enter into friendship delete forms so it routes
        # properly, never changes since the delete controller only worries about
        # the user_id
        @fake_friendship = Friendship.find(51)
      end
    

    index.html.erb

    <%= form_for [user, @fake_friendship], :method => :delete, :remote => true, html: {class: "unfriend"} do |f| %>
    <%= f.submit %>
    <% end %>
    

    【讨论】:

      【解决方案2】:

      尝试在@friendship.destroy 之后添加redirect_to friendship_path, status: 303

      如果您使用除 GET 或 POST 之外的 XHR 请求并在请求之后进行重定向,那么某些 > 浏览器将使用原始请求方法跟随重定向。这可能会导致不希望的 > 行为,例如双重 DELETE。要解决此问题,您可以返回 303。请参阅其他状态代码>将使用 GET 请求进行跟踪。

      来源:http://api.rubyonrails.org/classes/ActionController/Redirecting.html#method-i-redirect_to

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-10
        • 2020-07-01
        • 1970-01-01
        • 2022-11-26
        • 2013-11-11
        • 1970-01-01
        • 2021-09-06
        相关资源
        最近更新 更多