Ruby on Rails路由错误

时间:2017-05-26 13:26:50

标签: ruby-on-rails ruby amistad

我正在使用Amistad来实现友谊模型。我在friendships_controller中有五个操作:indexrequest_friendapprove_friendremove_friendblock_friend

我不确定如何在路由文件中定义路由,我尝试使用resources :friendships但无法从用户个人资料中发出好友请求。

以下是文件:

routes.rb中:

resources :friendships

friendships_controller.rb:

class FriendshipsController < ApplicationController
    before_filter :authenticate_user!

    def index
        @friends = current_user.friends
        @pending_invited_by = current_user.pending_invited_by
        @pending_invited = current_user.pending_invited
    end

    def request_friend
        @friend = User.find(params[:id])
        #if !@friend
        #    redirect_to :back
        #end
        current_user.invite @friend
        redirect_to :back
    end

    def approve_friend
        @friend = User.find(params[:id])
        current_user.approve @friend
        redirect_to :back
    end

    def remove_friend
        @friend = User.find(params[:id])
        current_user.remove_friendship @friend
        redirect_to :back
    end

    def block_friend
        @blocking = User.find(params[:id])
        current_user.block @blocking
        redirect_to :back
    end
end

我希望用户A能够向用户B发送朋友请求,并希望用户B接受,删除或忽略它。

这是我的show.html.erb

<span> 
  <% if @user == current_user %>
    <%= link_to 'Edit Profile', edit_profile_path(@user.user_name),class: 'btn edit-button' %>
  <% elsif current_user.friend_with? @user %>Already Friends!
    <%= button_to "Delete!",friendship_path(id: @user.id, friendship_action: 'remove_friendship'), method: :delete, class: "btn btn-primary" %>
  <% elsif current_user.invited? @user %>Friend request sent!
    <%= button_to "Unsend!", friendship_path(id: @user.id), :method => :delete, class: "btn btn-small btn-primary" %>
  <% elsif current_user.invited_by? @user %>
    <%= button_to "Accept!", friendship_path(@user.id, friendship_action: 'approve'), :method => :patch, class: "btn btn-small btn-primary" %>
    <%= button_to "Reject!", friendship_path(@user.id, friendship_action: 'remove_friendship'), :method => :delete, class: "btn btn-small btn-primary" %>
  <% else %>
    <%= form_tag friendship_path(@user.id,friendship_action: 'invite') do %>
      <%= submit_tag "Request Friend", class: "btn btn-primary" %>
    <% end %>
  <% end %>
</span>

This is the process going on in console when i manually do the friendships-i.e. user1.invite user2-it is working and changes are being made in the friendhips table-i used sqlitebrowser to verify

Here is what is going on when i press the link_to in my show.html.erb.Ive only included parts of the console related to the friendship model

当我按下按钮时,我不知道为什么没有插入值。但是当我通过控制台手动插入它们时。

2 个答案:

答案 0 :(得分:0)

如果我理解正确,这就是你的routes.rb应该是什么样子

您可以将块传递给resources方法以定义嵌套资源。

resources :friendships do
  member do
    post 'approve_friendship', to: 'friendships#approve_friendship'
    post 'request_friendship', to: 'friendships#request_friendship'
    delete 'remove_friendship', to: 'friendships#remove_friendship'
    post 'block_friendship', to: 'friendships#block_friendship'
  end
end

这会将端点定义为POST /friendships/:id/approve_friendship

您应该查看rails doc以获取更多信息:http://guides.rubyonrails.org/routing.html#adding-more-restful-actions

答案 1 :(得分:0)

为什么不使用标准动词?

class FriendshipsController < ApplicationController

  before_filter :authenticate_user!

  def index
    @friends = current_user.friends
    @pending_invited_by = current_user.pending_invited_by
    @pending_invited = current_user.pending_invited
  end

  def new
    @friend = User.find(params[:id])
    current_user.invite @friend
    redirect_to :back
  end

  def create
    @friend = User.find(params[:id])
    current_user.approve @friend
    redirect_to :back
  end

  def update
    @friend = User.find(params[:id])
    current_user.send blocking_method, @friend
    redirect_to :back
  end

  def destroy
    @friend = User.find(params[:id])
    current_user.remove_friendship @friend
    redirect_to :back
  end

private

  def blocking_method
    current_user.blocking?(@friend) ? :unblock : :block
  end

end

然后你可以这样做:

resources :friendships

就像你开始时一样,不必随意使用你的路线。

此外,在update方法(又名“阻止”)中,我添加了一个切换按钮,以便您可以允许用户阻止和取消阻止朋友。

现在,当你查看你的方法时,除了在current_user上进行的调用之外,它们基本相同。那么为什么不减肥呢?

class FriendshipsController < ApplicationController
  ALLOWED_FRIENDSHIP_ACTIONS = %w('invite' 'approve' 'remove_friendship' 'block', 'unblock')

  before_filter :authenticate_user!

  def index
    @friends = current_user.friends
    @pending_invited_by = current_user.pending_invited_by
    @pending_invited = current_user.pending_invited
  end

  def update
    @friend = User.find(params[:id])
    current_user.send(friendship_action, @friend) if friendship_action
    redirect_to :back
  end

private

  def friendship_action
    if fa = params[:friendship_action]
      return fa if ALLOWED_FRIENDSHIP_ACTIONS.include?(fa)
    end
  end

end

然后你可以这样做:

resources :friendships, :only => [:index, :update]

使用类似的东西:

link_to friendship_path(id: @friend.id, friendship_action: 'invite'), method: :patch

根据您的@friend.id(或link_to生成位置,取决于您的操作方式),您必须使用form位进行调整。

我不知道。对我来说,这似乎更清晰的代码。更少的线条,更少的重复,更紧密地遵循惯例。但是,不管你的小船是什么漂浮。

回应评论

尝试以下更改...

此:

    <%= button_to "Delete!",friendship_path(id: @user.id, friendship_action: 'remove_friendship'), method: :delete, class: "btn btn-primary" %>

应该是这样的:

    <%= button_to "Delete!", friendship_path(id: @user.id, friendship_action: 'remove_friendship'), method: :patch, class: "btn btn-primary" %>

为什么呢?因为您不再使用delete方法,请记住吗?仅限indexpatch

改变这个:

    <%= button_to "Unsend!", friendship_path(id: @user.id), :method => :delete, class: "btn btn-small btn-primary" %>

对此:

    <%= button_to "Unsend!", friendship_path(id: @user.id, friendship_action: 'unsend'), method: :patch, class: "btn btn-small btn-primary" %>

你需要助手里面的friendship_action。而且,:delete再次成为:patch

此:

    <%= button_to "Accept!", friendship_path(@user.id, friendship_action: 'approve'), :method => :patch, class: "btn btn-small btn-primary" %>

我会改为:

    <%= button_to "Accept!", friendship_path(id: @user.id, friendship_action: 'approve'), method: :patch, class: "btn btn-small btn-primary" %>

id:前添加@user.id可能就是问题所在。在这里,您获得了:method,但我会重新格式化为method: :patch只是为了保持一致。

下面:

    <%= button_to "Reject!", friendship_path(@user.id, friendship_action: 'remove_friendship'), :method => :delete, class: "btn btn-small btn-primary" %>

更改为:

    <%= button_to "Reject!", friendship_path(id: @user.id, friendship_action: 'remove_friendship'), method: :patch, class: "btn btn-small btn-primary" %>

id:delete添加到:patch

最后,这个:

    <%= form_tag friendship_path(@user.id,friendship_action: 'invite') do %>
      <%= submit_tag "Request Friend", class: "btn btn-primary" %>
    <% end %>

对此:

    <%= button_to "Request Friend", friendship_path(id: @user.id, friendship_action: 'invite'), method: :patch, class: "btn btn-primary" %>

您在其他地方使用button_to。为什么不在这里呢?

在这里,所有在一起:

<span> 
  <% if @user == current_user %>
    <%= link_to 'Edit Profile', edit_profile_path(@user.user_name),class: 'btn edit-button' %>
  <% elsif current_user.friend_with? @user %>Already Friends!
    <%= button_to "Delete!", friendship_path(id: @user.id, friendship_action: 'remove_friendship'), method: :patch, class: "btn btn-primary" %>
  <% elsif current_user.invited? @user %>Friend request sent!
    <%= button_to "Unsend!", friendship_path(id: @user.id, friendship_action: 'unsend'), method: :patch, class: "btn btn-small btn-primary" %>
  <% elsif current_user.invited_by? @user %>
    <%= button_to "Accept!", friendship_path(id: @user.id, friendship_action: 'approve'), method: :patch, class: "btn btn-small btn-primary" %>
    <%= button_to "Reject!", friendship_path(id: @user.id, friendship_action: 'remove_friendship'), method: :patch, class: "btn btn-small btn-primary" %>
  <% else %>
    <%= button_to "Request Friend", friendship_path(id: @user.id, friendship_action: 'invite'), method: :patch, class: "btn btn-primary" %>
</span>