2016-12-08 1 views
0

나는 여기에있는 지침에 따라 사용자가 "소프트 삭제됨"을 허용하도록 devises를 사용하고 등록 컨트롤러를 오버라이드했습니다 : devise/wiki/How-to:-Soft-delete-a-user.이 rspec 테스트에서 평가되기 전에이 속성이 손실되는 이유는 무엇입니까?

나는 테스트를 따라 내 코드를 통해 일부 puts 명령을 넣어했습니다 내 RSpec에 결과는 다음과 같다 다음 puts 쇼로

10:00:30 - INFO - Running: spec/controllers/users/registrations_controller_spec.rb 
    .. 
> BEFORE: id:2, deleted_at: 
> -- model: id:2, deleted_at:2016-12-08 15:00:35 UTC 
> -- controller: id:2, deleted_at:2016-12-08 15:00:35 UTC 
> AFTER: id:2, deleted_at: 
    F.. 

    Failures: 

     1) Users::RegistrationsController GET #destroy sets 'deleted_at' date for user 
     Failure/Error: expect(user.deleted_at).to_not be_nil 

      expected: not nil 
       got: nil 
     # ./spec/controllers/users/registrations_controller_spec.rb:44:in `block (3 levels) in <top (required)>' 

    Finished in 0.37438 seconds (files took 3.7 seconds to load) 
    5 examples, 1 failure 

, 내 사용자가 null로 설정 deleted_at 필드로 시작. 모델은 deleted_at을 현재 시간으로 설정하고 컨트롤러는 날짜가 설정되었음을 확인하지만 내 테스트에서 내 expect() 성명서에 도착할 때까지 user.deleted_atnil으로 돌아갑니다. 응용 프로그램이 제대로 작동하기 때문에 테스트에 문제가있는 것으로 보입니다.

/spec/controllers/users/registrations_controller_spec.rb

require 'rails_helper' 
    require 'factory_girl_rails' 

    RSpec.describe Users::RegistrationsController, type: :controller do  
    include Devise::Test::ControllerHelpers 

    describe "GET #destroy" do 

     it "sets 'deleted_at' date for user" do 
      request.env["devise.mapping"] = Devise.mappings[:user] 

      # sign-in user 
      user = FactoryGirl.create(:user_for_account_update) 
      sign_in(user, scope: :user) # note: does not verify correct password 

      # soft-delete user 
      puts "BEFORE: id:#{user.id}, deleted_at:#{user.deleted_at}" 
      delete :destroy, {:id => user.id} 
      puts "AFTER: id:#{user.id}, deleted_at:#{user.deleted_at}" 

      expect(user.deleted_at).to_not be_nil 
     end 
    end 
    end 

/spec/factories/user.rb

require 'ffaker' 

FactoryGirl.define do 
    factory :user do |u| 
    @pass = "password" 

    name FFaker::Name.name 
    email { |me| "#{name.to_s.gsub(/\s/,'.')}_#{rand(1000).to_s}@testing.com" } 
    password @pass 

    factory :user_for_account_update do 
     password_confirmation @pass 
     confirmed_at Date.today 
    end 
    end 
end 

/app/models/user.rb

... 

    # instead of deleting, indicate the user requested a delete & timestamp it 
    def soft_delete 
    update_attribute(:deleted_at, Time.current) 
    puts " -- model: id:#{id}, deleted_at:#{deleted_at.to_s}" 
    end 

    ... 

/app/controllers/users/registrations_controller.rb 당신은이 (deleted_at 포함) 값을 캐시 된 있도록 컨트롤러 액션 전에 만들어진 user를 사용하는

# This class overrides devise's registration controller. All 
# other devise actions remain (I believe) handled as usual by 
# devise. I think it is the route that does that by specifying 
# this controller specifically for the purpose of registrations 
# 
# see also: http://stackoverflow.com/questions/3546289 
class Users::RegistrationsController < Devise::RegistrationsController 
    before_filter :configure_permitted_parameters, if: :devise_controller? 

    # SOFT DELETE /resource 
    # Follows devise guide: https://github.com/plataformatec/devise/wiki/How-to:-Soft-delete-a-user-when-user-deletes-account 
    def destroy 
    resource.soft_delete 
    Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name) 
    set_flash_message :notice, :destroyed if is_flashing_format? 
    yield resource if block_given? 
    respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) } 
    puts " -- controller: id:#{resource.id}, deleted_at:#{resource.deleted_at}" 
    end 

    protected 

    # we have to explicitly permit params in overridden controllers like this 
    # see https://github.com/plataformatec/devise#strong-parameters 
    def configure_permitted_parameters 
    devise_parameter_sanitizer.permit(:sign_up) do |u| 
     u.permit(:name, :email, :password, :password_confirmation) 
    end 
    devise_parameter_sanitizer.permit(:account_update) do |u| 
     u.permit(:name, :email, :password, :password_confirmation, :current_password) 
    end 
    end 
end 
+1

당신은 DB에서 정보를 업데이트하려면'user.reload'을 할 봤어에서 업데이트 속성을 가져올 user.reload를 사용할 수 있습니까? – faron

+0

나는 그것에 대해 몰랐다 (나는 레일에 아주 새로웠다.). 완벽한 이해와 문제 해결 - 감사합니다! – doub1ejack

답변

관련 문제