2013-10-31 49 views
0

编辑1:当我检查unfollow提交按钮的元素并将url末尾的变量更改为一个我知道是一个关系行ID它会删除正确的行但后来告诉我,找不到具有该ID的用户将我重定向到。所以我认为它是发送用户id到destroy方法,如果没有该id的行存在会引发错误,或者如果退出时删除错误的关系。然后它使用相同的变量将您重新路由回您正在查看的用户配置文件。无法删除特定表中的特定行

edit2:通过向视图中的form_tag添加(@关系)已解决了取消关注部分。现在关系控制器'redirect_to user_path params [:id]'中的重定向正在寻找用户控制器中的索引方法,因为我想我希望它查找show方法,所以我现在想要找出那部分

我正在关注rails教程并遇到问题。从评论的教程代码是错误的,所以我想知道如果有人在这里可以指向我的解决方案,所以我可以继续本教程的其余部分

我有用户谁可以创建帖子(ribbits)。用户可以关注其他用户。我正在尝试使用取消关注功能。有一个关系表,其中包含字段id,follower_id,followed_id和时间戳。

关系创建方法工作正常,所有字段正确填充。当我点击取消关注我收到以下错误

的ActiveRecord :: RecordNotFound在RelationshipsController#破坏 无法找到ID关系= 2

它指向这个代码从relationships_controller行::销毁方法

 @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.+-][email protected]([\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

真正的问题就出在这行:

<%= form_tag relationship_path, method: :delete do %> 

我怀疑你在表演方法抬头的@relationship应提供在url帮手:

<%= form_tag relationship_path(@relationship), method: :delete do %> 

在Rails的当前版本,你甚至可以缩短这:

<%= form_tag @relationship, method: :delete do %> 

假设你的模型(关系)并有一个相应的控制器(RelationshipsController),那么Rails将正确地从你的实例变量推断出url。

我想第二个musicnerd47的建议,这应该是一个链接,而不是一个形式。

<%= link_to 'Unfollow', @relationship, method: :delete %> 

这样会更容易风格。

+0

感谢这大多解决了这个问题,但是当这部分'redirect_to user_path params [:followed_id]'重定向时,它会查找索引方法,当我想让它查找show方法时 – Ir1sh

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