[英]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
有五个动作: index
, request_friend
, approve_friend
, remove_friend
, block_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
. 只有
index
和patch
。
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.