【问题标题】:Add tests for dependent :destroy in the Relationship model (Chapter 11, Exercise 1 Rails Tutorial, 2nd Ed)在关系模型中添加依赖 :destroy 的测试(第 11 章,练习 1 Rails 教程,第 2 版)
【发布时间】:2012-05-02 12:06:34
【问题描述】:

非常确定这些测试工作正常。通过删除 user.rb 中 has_many :relationships 和 has_many :reverse_relationships 上的依赖: :destroy 选项让它们失败。

想分享我所做的事情,以防其他人通过Michael Hartl's Rails Tutorial 2nd Edition, Chapter 11 Exercises.

这个练习提出了几个问题(见本文底部)。如果有人可以提供帮助,那就太好了。

第 11 章,练习 1:

按照清单 10.15 中的示例,在关系模型(清单 11.4 和清单 11.16)中添加依赖 :destroy 的测试。

这是我的测试: spec/models/user_spec.rb

require 'spec_helper'

describe User do

  before do
  @user = User.new(name: "Example User", email: "user@example.com", 
                   password: "foobar", password_confirmation: "foobar")
  end

  subject { @user }

  [...code omitted...]

  describe "relationship associations" do
    let(:other_user) { FactoryGirl.create(:user) }
    before do
      @user.save
      @user.follow!(other_user)
      other_user.follow!(@user)
    end

    it "should destroy associated relationships" do
      relationships = @user.relationships
      @user.destroy
      relationships.should be_empty
    end

    it "should destroy associated reverse relationships" do
      reverse_relationships = @user.reverse_relationships
      @user.destroy
      reverse_relationships.should be_empty
    end
  end

这个练习提出了几个问题:

问题 1:

我最初的测试是 关系。应该是_nil reverse_relationships.should be_nil

但是,尽管没有用户存在,但仍会返回一个数组。 那么,当用户不存在,调用关联方法时,结果还是数组?总是这样吗?

问题 2:

我想尝试在 rails 控制台中为用户删除关系和 reverse_relationships。

我试过了

> user = User.first
> user.relationships
 # returns a bunch of relationships
> user.relationships.destroy
=> []
> user.relationships
 # returns same bunch of relationships

我如何真正永久地破坏这种关系?在控制台中探索似乎是一件好事。

谢谢!我对 Rails 还是很陌生

【问题讨论】:

    标签: ruby-on-rails-3 railstutorial.org rails-console dependent-destroy


    【解决方案1】:

    可能你需要这样的 smt

    it { should have_many(:relationships).dependent(:destroy) }
    

    【讨论】:

      【解决方案2】:

      我也是一个 ruby​​/rails 菜鸟。

      问题 1: 在rubyonrails.org 中搜索has_many 并显示

      返回所有关联对象的数组。如果没有找到则返回一个空数组。

      附带说明,您可以同时测试 nil 和 empty:

      relationships.present?.should be_false
      

      问题 2: user.relationships.destroy 需要一个 :id

      user.relationships.destroy '1'
      

      【讨论】:

        【解决方案3】:

        感谢您发布带有问题的代码。我只想将此作为评论而不是答案发布,但似乎我还不能。无论如何,我只是想在您的测试中添加一个小的潜在候选人,但从other_user 的角度来看。该测试类似于关注/取消关注测试,因此希望它不会太多余,但它直接测试relationships,而不是通过它们的followed_usersfollowers

        describe "relationship associations" do
          ...
          context "when a follower/followed user is destroyed" do
            subject { other_user }
        
            before { user.destroy }
        
            its(:relationships) { should_not include(user) }
            its(:reverse_relationships) { should_not include(user) }
          end
        end
        

        【讨论】:

          【解决方案4】:

          Ruby on Rails Tutorial 2nd Edition.

          练习 11.5.1 添加测试以破坏与给定用户关联的关系。

          此代码对我有用。我尝试按照示例Listing 10.15 进行操作。

          spec/models/user_spec.rb

          require 'spec_helper'
          
          describe User do
          
            before do 
              @user = User.new(name: "Example User", email: "user@example.com", password: "foobar", password_confirmation: "foobar")
            end
          
            subject { @user }
            .
            .
            .
            .
            describe "user relationships associations" do
              let (:other_user) { FactoryGirl.create(:user) }
              let (:another_user) { FactoryGirl.create(:user) }
          
              before do
                @user.save
                @user.follow!(other_user)
                @user.follow!(another_user)
                other_user.follow!(@user)
                other_user.follow!(another_user)
                another_user.follow!(@user)
                another_user.follow!(other_user)
              end
          
              its(:followed_users) { should include(other_user) }
              its(:followers) { should include(another_user) }
          
              it "should destroy associated followers" do
                followers = @user.followers
                @user.destroy
                followers.each do |follower|
                  follower.followed_users.should_not include(@user)
                end
              end
          
              it "should destroy associated followed users" do
                followed_users = @user.followed_users
                @user.destroy
                followed_users.each do |followed_user|
                  followed_user.followers.should_not include(@user)
                end
              end
            end
          end
          

          【讨论】:

            【解决方案5】:

            Re: paul,relationships 数组不是由用户构成的,所以他的 include() 应该总是为 false,所以测试总是绿色的。 回复:玛丽亚,即使引用他或她的关系仍然存在,followed_users 和 follower 方法似乎也不会返回不存在的用户。所以这个测试也永远不会是红色的。

            另一种解决方案:

              describe "relationships" do
                let(:other_user) { FactoryGirl.create(:user) }
                before do
                  @user.save
                  @user.follow!(other_user)
                end
            
                let(:relationship) { @user.relationships.last }
            
                describe "should be destroyed when the followed user is destroyed" do
                  before { other_user.destroy }
                  its(:relationships) { should_not include(relationship) }
                end
            
                describe "should be destroyed when the following user is destroyed" do
                  subject { other_user }
                  before { @user.destroy }
                  its(:reverse_relationships) { should_not include(relationship) }
                end
              end
            

            【讨论】:

              【解决方案6】:

              以上答案有效,但我想我会分享我的更短的......:D

              describe "following" do
              
                let(:other_user) { FactoryGirl.create(:user) }
                before do
                  @user.save
                  @user.follow!(other_user)
                  other_user.follow!(@user)
                end
              
                 it { should be_following(other_user) }
                 its(:followed_users) { should include(other_user) }
              
                 it "should destroy associated followed_users and followers" do
                   @user.destroy
                   @user.relationships.present?.should be_false
                   @user.reverse_relationships.present?.should be_false
              
                   expect(other_user.followers).not_to include(@user)
                   expect(other_user.followed_users).not_to include(@user)
                 end
                 .
                 .
                 .
                 .
               end
              end
              

              PS 你可以省略:

              @user.relationships.present?.should be_false
              @user.reverse_relationships.present?.should be_false
              

              但是我把它扔在那里是为了让那些想要确保所有相关的破坏动作都在起作用的人。

              【讨论】:

                猜你喜欢
                • 2012-05-02
                • 1970-01-01
                • 1970-01-01
                • 2012-06-12
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-04-30
                • 1970-01-01
                相关资源
                最近更新 更多