1

我正在使用 Amistad 来实现友谊模型。我在friendships_controller: index, request_friend, approve_friend, remove_friend,中有五个动作block_friend

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

以下是文件:

路线.rb:

resources :friendships

友谊控制器.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>

这是我手动执行友谊时在控制台中进行的过程 - 即 user1.invite user2 - 它正在工作并且正在对友谊表进行更改 - 我使用 sqlitebrowser 进行验证

这是我在 show.html.erb.Ive 中按 link_to 时发生的情况。我只包含与友谊模型相关的控制台部分

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

4

2 回答 2

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方法(又名“阻止”)中,我添加了一个切换按钮,以便您可以允许用户阻止和取消阻止朋友。

现在,当您查看您的方法时,除了调用 on 之外,它们基本上都是相同的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>
于 2017-05-26T14:18:39.980 回答
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 文档以获取更多信息: http: //guides.rubyonrails.org/routing.html#adding-more-restful-actions

于 2017-05-26T13:32:12.100 回答