所以我开始通过编写一个小型任务跟踪应用来学习rails。现在我试图重构以更安全一点。例如,在更新或销毁之前,我现在正在使用范围来确保您查看自己的任务。
在这样做之后,三个测试不再通过,我不确定如何解决它们。我究竟做错了什么?我是否需要更改测试或忘记对工厂做些什么?
谢谢!
**Task@controller**
def update
@task = current_user.tasks.where(id: params[:id])
authorize @task
if @task.update_attributes(task_params)
else
flash[:error] = "There was an error updating the todo."
end
respond_with(@task) do |format|
format.html { redirect_to tasks_path }
end
end
def destroy
@task = current_user.tasks.where(id: params[:id])
authorize @task
if @task.destroy
flash[:notice] = "Todo was deleted successfully."
else
flash[:error] = "There was an error deleting the todo."
end
respond_with(@task) do |format|
format.html { redirect_to tasks_path }
end
end
测试1和2
**task_controller_spec**
require 'rails_helper'
describe TasksController do
include Devise::TestHelpers
before do
@user = create(:user)
sign_in @user
end
describe '#update-completed' do
it "updates a task to be completed" do
task = create(:task, user: @user)
expect( task.completed ).to eq(false)
patch :update, id: task.id, task:{completed: true}
task.reload
expect( task.completed ).to eq(true)
end
end
describe '#destroy' do
it "deletes a task" do
task = create(:task, user: @user)
delete :destroy, id: task.id
expect( @user.tasks.count ).to eq(0)
end
end
end
测试3
**feature_spec**
require 'rails_helper'
feature "Task" do
include Warden::Test::Helpers
Warden.test_mode!
before do
@user = create(:user)
login_as(@user, :scope => :user)
end
feature "completes", js: true do
scenario "a task using a checkbox" do
task = create(:task, user: @user)
visit tasks_path
check("task[completed]")
expect( page ).to have_content('Todo completed!')
end
end
after do
Warden.test_reset!
end
end
导致......
1) TasksController#update-completed updates a task to be completed
Failure/Error: patch :update, id: task.id, task:{completed: true}
NoMethodError:
undefined method `user' for # <ActiveRecord::AssociationRelation::ActiveRecord_AssociationRelation_Task:0xc1e4450>
# /home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.9/lib/active_record/relation/delegation.rb:121:in `method_missing'
# /home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.9/lib/active_record/relation/delegation.rb:68:in `method_missing'
# ./app/policies/application_policy.rb:26:in `update?'
# /home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/pundit-0.3.0/lib/pundit.rb:70:in `public_send'
# /home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/pundit-0.3.0/lib/pundit.rb:70:in `authorize'
# ./app/controllers/tasks_controller.rb:28:in `update'
2) TasksController#destroy deletes a task
Failure/Error: delete :destroy, id: task.id
NoMethodError:
undefined method `user' for #<ActiveRecord::AssociationRelation::ActiveRecord_AssociationRelation_Task:0xc51965c>
# /home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.9/lib/active_record/relation/delegation.rb:121:in `method_missing'
# /home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.9/lib/active_record/relation/delegation.rb:68:in `method_missing'
# ./app/policies/application_policy.rb:26:in `update?'
# ./app/policies/application_policy.rb:34:in `destroy?'
# /home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/pundit-0.3.0/lib/pundit.rb:70:in `public_send'
# /home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/pundit-0.3.0/lib/pundit.rb:70:in `authorize'
# ./app/controllers/tasks_controller.rb:42:in `destroy'
3) Task completes a task with a checkbox
Failure/Error: Unable to find matching line from backtrace
NoMethodError:
undefined method `user' for #<ActiveRecord::AssociationRelation::ActiveRecord_AssociationRelation_Task:0xbe5fb04>
# /home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.9/lib/active_record/relation/delegation.rb:121:in `method_missing'
# /home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.9/lib/active_record/relation/delegation.rb:68:in `method_missing'
# ./app/policies/application_policy.rb:26:in `update?'
# /home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/pundit-0.3.0/lib/pundit.rb:70:in `public_send'
# /home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/pundit-0.3.0/lib/pundit.rb:70:in `authorize'
# ./app/controllers/tasks_controller.rb:28:in `update'
任务工厂
**task factory**
FactoryGirl.define do
factory :task do
description "MyText"
user nil
completed false
end
end
答案 0 :(得分:2)
更改
# Returns an ActiveRecord::AssociationRelation
@task = current_user.tasks.where(id: params[:id])
到
# Returns a single Task instance
@task = current_user.tasks.find(params[:id])
find
文档:http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-find