我通过以下链接http://railscasts.com/episodes/163-self-referential-association启发了自己,但是rspec测试并不容易。
用户模型:
class User < ActiveRecord::Base
# Associations
has_many :followerships
has_many :followers, :through => :followerships
has_many :inverse_followerships, :class_name => "Followership", :foreign_key => "follower_id"
has_many :inverse_followers, :through => :inverse_followerships, :source => :user
end
关注模式:
class Followership < ActiveRecord::Base
belongs_to :user
belongs_to :follower, :class_name => "User"
end
关注工厂:
FactoryGirl.define do
factory :followership do
user_id 1
follower_id 1
end
end
关注者控制器:
class FollowershipsController < InheritedResources::Base
def create
@followership = current_user.followerships.build(:follower_id => params[:follower_id])
if @followership.save
flash[:notice] = "Following."
redirect_to root_url
else
flash[:error] = "Unable to follow."
redirect_to root_url
end
end
def destroy
@followership = current_user.followerships.find(params[:id])
@followership.destroy
flash[:notice] = "Removed followership."
redirect_to current_user
end
end
folowerships控制器规范(这是完全错误的):
require 'rails_helper'
describe FollowershipsController do
let!(:followership) { create(:followership) }
let!(:follower) { followership.follower }
let!(:user) { create(:user) }
before do
sign_in :user, user
end
describe "#create" do
it "saves the followership" do
post :create, followership: { follower_id: follower }
expect(response).to redirect_to(root_path)
expect(assigns(:followership).followership.followers).to eq(user)
expect(flash[:notice]).to eq("Following.")
end
it "fails to save followership" do
expect(post :create, followership: { follower_id: follower }).to redirect_to(root_path)
expect(flash[:notice]).to eq("Unable to follow.")
end
end
describe "#destroy" do
it "deletes the followership" do
expect {
delete :destroy, id: follower
}.to change(Followership, :count).by(-1)
expect(flash[:notice]).to eq("Removed followership.")
end
end
end
来自关注者控制器Rspec的错误
FollowershipsController
#destroy
deletes the followership (FAILED - 1)
#create
saves the followership (FAILED - 2)
fails to save followership (FAILED - 3)
Failures:
1) FollowershipsController#destroy deletes the followership
Failure/Error: delete :destroy, id: follower
ActionController::UrlGenerationError:
No route matches {:action=>"destroy", :controller=>"followerships", :id=>nil}
2) FollowershipsController#create saves the followership
Failure/Error: expect(assigns(:followership).followership.followers).to eq(user)
NoMethodError:
undefined method `followership' for #<Followership:0x00000109f69780>
3) FollowershipsController#create fails to save followership
Failure/Error: expect(flash[:notice]).to eq("Unable to follow.")
expected: "Unable to follow."
got: "Following."
(compared using ==)
感谢您的帮助:)
答案 0 :(得分:2)
let
命令使用延迟评估,因此在调用之前不会实际创建这些记录。使用let!
语法确保在测试运行之前创建它们:
let!(:followership) { create(:followership) }
let!(:follower) { followership.follower }
let!(:user) { create(:user) }
如果对于该对用户尚未存在,则确保您的验证仅允许创建以下用户:
class Followership < ActiveRecord::Base
validates_uniqueness_of :user_id, scope: :follower_id
此外,由于follower
不一定有followership
,因此无法保证user
/ user
关系属于id
。assigns
1}} 1。
最后,assigns(:followership)
是一种方法,因此语法应为assigns[:followership]
而不是Notice: Undefined index: soft_id in C:\xampp\htdocs\SLR\Update S110 PC01.php on line 14
Notice: Undefined index: soft_name in C:\xampp\htdocs\SLR\Update S110 PC01.php on line 15
Notice: Undefined index: installed_date in C:\xampp\htdocs\SLR\Update S110 PC01.php on line 16
Notice: Undefined index: expiry_date in C:\xampp\htdocs\SLR\Update S110 PC01.php on line 17
Notice: Undefined index: product_key in C:\xampp\htdocs\SLR\Update S110 PC01.php on line 18
Fatal error: Uncaught Error: Call to undefined function mysql_query() in C:\xampp\htdocs\SLR\Update S110 PC01.php:22 Stack trace: #0 {main} thrown in C:\xampp\htdocs\SLR\Update S110 PC01.php on line 22