简体   繁体   English

Ruby on Rails路由错误

[英]Ruby on Rails Routes Error

I am using Amistad to implement the friendship model. 我正在使用Amistad来实现友谊模型。 I have five actions in the friendships_controller : index , request_friend , approve_friend , remove_friend , block_friend . 我在friendships_controller有五个动作: indexrequest_friendapprove_friendremove_friendblock_friend

I am not sure on how to define the routes in the routes file, I tried using resources :friendships but am unable to make a friend request from the user profile. 我不确定如何在路由文件中定义路由,我尝试使用resources :friendships但无法从用户配置文件中发出好友请求。

Here are the files: 这是文件:

routes.rb: routes.rb中:

resources :friendships

friendships_controller.rb: 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

I want User A to be able to send User B a friend request and User B to either accept it, delete it or ignore it. 我希望用户A能够向用户B发送朋友请求,并且用户B要么接受它,要么删除它或忽略它。

Here is my show.html.erb 这是我的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-ie user1.invite user2-it is working and changes are being made in the friendhips table-i used sqlitebrowser to verify 当我手动执行友谊时,这是在控制台中进行的过程 - 即user1.invite user2 - 它正在工作并且正在友谊表中进行更改 - 我使用sqlitebrowser来验证

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 这是我在show.html.erb中按下link_to时发生的事情。我只包含与友谊模型相关的控制台部分

I dont know why the values are not being inserted when i press the button.But when i do it manually via the console they are being inserted. 当我按下按钮时,我不知道为什么没有插入值。但是当我通过控制台手动插入它们时。

If I understood correctly this is how your routes.rb should look like 如果我理解正确,这就是你的routes.rb应该是这样的

You can pass a block to the resources method to define nested resources. 您可以将块传递给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

This will define the endpoints as POST /friendships/:id/approve_friendship 这将端点定义为POST /friendships/:id/approve_friendship

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

Why not just use the standard verbs? 为什么不使用标准动词呢?

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

Then you can just do: 然后你可以这样做:

resources :friendships

Like you started with and not have to monkey around with your routes. 就像你开始时一样,而不必随身携带你的路线。

Also, in the update method (aka, 'blocking'), I added a toggle so that you can allow a user to block and unblock a friend. 此外,在update方法(又名“阻止”)中,我添加了一个切换按钮,以便您可以允许用户阻止和取消阻止朋友。

Now, when you look at your methods, they are all essentially identical except for the call being made on current_user . 现在,当你查看你的方法时,除了在current_user上进行的调用之外,它们基本相同。 So why not slim things down? 那么为什么不减肥呢?

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

And then you could do: 然后你可以这样做:

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

And use it something like: 并使用它像:

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

You'll have to monkey with that @friend.id bit a little depending on where you are generating your link_to (or your form , depending on how you're doing it). 根据您生成link_to (或您的form ,具体取决于您的工作form ,您必须使用@friend.id位一点点。

I don't know. 我不知道。 To me, that seems like cleaner code. 对我来说,这似乎更清晰的代码。 Fewer lines, less repetition, more closely following convention. 更少的线条,更少的重复,更紧密地遵循惯例。 But, whatever floats your skiff. 但是,无论什么漂浮你的小船。

RESPONSE TO COMMENT 对评论的回应

Try the changes below... 请尝试以下更改...

This: 这个:

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

Should be this: 应该是这样的:

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

Why? 为什么? Because you don't have a delete method anymore, remember? 因为你不再有delete方法,记得吗? Only index and patch . 只有indexpatch

Change this: 改变这个:

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

To this: 对此:

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

You need the friendship_action inside the helper. 你需要helper里面的friendship_action And, again, :delete becomes :patch . 而且,再次, :delete变为:patch

This: 这个:

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

I would change to: 我会改为:

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

Adding id: in front of @user.id may be the thing. 添加id:@user.id前面可能就是这样。 Here, you got the :method , but I would reformat to method: :patch just to be consistent. 在这里,你得到了:method ,但我会重新格式化为method: :patch只是为了保持一致。

Here: 这里:

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

Change to: 改成:

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

Adding id and :delete to :patch . 添加id:delete to :patch

Finally, this: 最后,这个:

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

To this: 对此:

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

You're using button_to everywhere else. 你在其他地方使用button_to Why not here, too? 为什么不在这里呢?

Here it is, all together: 在这里,所有在一起:

<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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM