编辑1:当我检查元素的unfollow提交按钮并将url末尾的变量更改为一个我知道的关系行id时它会删除正确的行然后告诉我它无法找到具有该行的用户id将我重定向到。所以我认为它是将用户id发送到destroy方法,如果没有具有该id的行,则会出现错误,如果退出则删除错误的关系。然后,它使用相同的变量将您重新路由回您正在查看的用户配置文件。
edit2:通过将(@relationship)添加到视图中的form_tag来解决取消关注部分。现在关系控制器'redirect_to user_path params [:id]'中的重定向正在寻找用户控制器中的索引方法,当我想要它寻找show方法时所以我现在想要找出那个部分
我正在关注rails教程并遇到了问题。从评论中,教程代码是错误的,所以我想知道这里是否有人可以指出我的解决方案,所以我可以继续本教程的其余部分
我有用户可以创建帖子(ribbits)。用户可以关注其他用户。我试图让unfollow功能工作。有一个关系表,其中包含字段id,follower_id,followed_id和timestamps。
关系create方法工作正常,所有字段都正确填充。当我点击取消关注后,我收到以下错误
RelationshipsController中的ActiveRecord :: RecordNotFound#destroy 无法找到与id = 2的关系
它指向relations_controller :: destroy方法
中此代码的行 @relationship = Relationship.find(params[:id])
我不确定params [:id]来自何处或为何使用它。从我可以告诉跟随的人用户ID被传递给destroy方法而不是实际的关系id
这是代码的其余部分
relationshipsController
class RelationshipsController < ApplicationController
def create
@relationship = Relationship.new
@relationship.followed_id = params[:followed_id]
@relationship.follower_id = current_user.id
if @relationship.save
redirect_to User.find params[:followed_id]
else
flash[:error] = "Couldn't Follow"
redirect_to root_url
end
end
def destroy
@relationship = Relationship.find(params[:id])
@relationship.destroy
redirect_to user_path params[:id]
end
end
用户模型
class User < ActiveRecord::Base
before_save :create_avatar_url
has_secure_password
has_many :ribbits
has_many :follower_relationships, class_name: "Relationship", foreign_key: "followed_id"
has_many :followed_relationships, class_name: "Relationship", foreign_key: "follower_id"
has_many :followers, through: :follower_relationships
has_many :followeds, through: :followed_relationships
validates :name, presence: true
validates :username, uniqueness: true, presence: true
validates :email, uniqueness: true, presence: true, format: { with: /\A[\w.+-]+@([\w]+.)+\w+\z/ }
before_validation :prep_email
def create_avatar_url
self.avatar_url = "http://www.gravatar.com/avatar/#{Digest::MD5.hexdigest(self.email)}?s=50"
end
def following? user
self.followeds.include? user
end
def follow user
Relationship.create follower_id: self.id, followed_id: user.id
end
private
def prep_email
self.email = self.email.strip.downcase if self.email
end
end
用户控制器
class UsersController < ApplicationController
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
session[:user_id] = @user.id
redirect_to @user, notice: "Thank you for signing up for Ribbit!"
else
render 'new'
end
end
def show
@user = User.find(params[:id])
@ribbit = Ribbit.new
@relationship = Relationship.where(
follower_id: current_user.id,
followed_id: @user.id
).first_or_initialize if current_user
end
private
def user_params
params.require(:user)
.permit(:avatar_url, :email, :name, :password, :password_confirmation, :username)
end
end
show.html.erb
<% if current_user %>
<div id="createRibbit" class="panel right">
<h1>Create a Ribbit</h1>
<p>
<%= form_for @ribbit do |f| %>
<%= f.text_area :content, class: 'ribbitText' %>
<%= f.submit "Ribbit!" %>
<% end %>
</p>
</div>
<% end %>
<div id="ribbits" class="panel left">
<h1>Your Ribbit Profile</h1>
<div class="ribbitWrapper">
<img class="avatar" src="<%= @user.avatar_url %>">
<span class="name"><%= @user.name %></span> @<%= @user.username %>
<p>
<%= @user.ribbits.size %> Ribbits
<span class="spacing"><%= @user.followers.count %> Followers</span>
<span class="spacing"><%= @user.followeds.count %> Following</span>
</p>
<% if current_user and @user != current_user %>
<% if current_user.following? @user %>
<%= form_tag relationship_path, method: :delete do %>
<%= submit_tag "Unfollow" %>
<% end %>
<% else %>
<%= form_for @relationship do %>
<%= hidden_field_tag :followed_id, @user.id %>
<%= submit_tag "Follow" %>
<% end %>
<% end %>
<% end %>
</div>
</div>
<div class="panel left">
<h1>Your Ribbits</h1>
<% @user.ribbits.each do |ribbit| %>
<div class="ribbitWrapper">
<img class="avatar" src="<%= @user.avatar_url %>">
<span class="name"><%= @user.name %></span>
@<%= @user.username %>
<span class="time"><%= time_ago_in_words(ribbit.created_at) %></span>
<p> <%= ribbit.content %> </p>
</div>
<% end %>
</div>
答案 0 :(得分:0)
params散列是传递给控制器动作的任何东西。调试它的一种好方法是使用raise params.to_yaml
作为控制器操作的第一行。它可以让你看到传入的内容。目前看起来你并没有传递你应该摧毁的关系。为什么不尝试使用:
<%= form_tag relationship_path(@user.followed_relationships.where(follower: current_user)), method: :delete do %>
或者,我绝对不会为你的取消关注方法使用整个表单。为什么不直接使用链接?而不是形式,你可以尝试类似的东西:
<%= link_to('Unfollow', relationship_path(@user.followed_relationships.where(follower: current_user)), method: :delete) %>
答案 1 :(得分:0)
问题实际上在于这一行:
<%= form_tag relationship_path, method: :delete do %>
我怀疑你在show方法中查找的@relationship应该在url helper中提供:
<%= form_tag relationship_path(@relationship), method: :delete do %>
在当前版本的Rails中,您甚至可以将其缩短为:
<%= form_tag @relationship, method: :delete do %>
假设您的模型(Relationship)并且具有相应的控制器(RelationshipsController),那么Rails将正确地从您的实例变量推断出url。
我的第二个音乐家47的建议是,这应该是链接而不是表格。
<%= link_to 'Unfollow', @relationship, method: :delete %>
风格会更容易。