简体   繁体   中英

Rails 3.2 reload! not working as expected

I am trying to test a create action on my users controller. The ask is to allow customers who have previously created accounts, but never actually created a subscription, to use the same email at signup but not be bound to their original password. My test is as follows:

 it "updates the user password for user with no entitlement" do
    user6 = Factory(:user)
    user_params_without_entitlement= { :email => user6.email, :password => "mynewpassword", :password_confirmation => "mynewpassword", publisher_id: user6.publisher_id }

    post :create, user_params_without_entitlement
    hash = Hashie::Mash.new(JSON.parse response.body)
    expect(hash[:errors].present?).to eq(false)
    expect(user6.password).to eq("mynewpassword")
  end

my controller looks like:

def create
if @user.save && @user.activate!
      render :create, status: 200
    elsif @user.errors[:email].first == "Oops! Looks like you've already created an account. Please <a href='/account'>click here to sign in.</a>"
      user = User.find_by_email(params[:email])

      if user.user_entitlements.empty? && user.update_attributes(password: params[:password], password_confirmation: params[:password_confirmation])
        render :create, status: 200
      else
        render json: {errors: @user.errors}, status: 422
      end
    else
      if render json: {errors: @user.errors}, status: 422
      end
    end
end

If I put a binding in below the

user.user_entitlements.empty? && user.update_attributes(password: params[:password], password_confirmation: params[:password_confirmation])

and I call user.password I get "mynewpassword" so the password is updating. in the test though the password is still showing as the original password. I tried adding user6.reload! in the test before the expectation block and I get

NoMethodError: undefined method `reload!' for #<User:0x007fa9a3342fc0>

I found this issue: https://github.com/rweng/pry-rails/issues/9 which suggests that I should modify my .pryrc file. I didn't have a .pryrc file previously. I created a .pryrc file and tried everything in this post( pry gem how to reload? ) one at a time with no success. I created the .pryrc in the root of the app and at this point I am at a loss as to what to do.

it is object.reload to reload an object - without the !bang inside the console you use reload! to reload the hole application models.

so in your case do user6.reload

just to clearout for you, how to use object.reload correctly

User has one profile which has autosave. After_save of profile, the profile is calculating the age and writes that to the user.

[69] pry(main)> a = User.last    
[70] pry(main)> a.age
=> 80

[71] pry(main)> a.profile.birthday = 18.years.ago
[72] pry(main)> a.save
......
  SQL (0.3ms)  UPDATE "users" SET "age" = 18 WHERE "users"."id" = $1  [["id", 6]]
....

[73] pry(main)> a.age
=> 80

[74] pry(main)> a.reload

[75] pry(main)> a.age
=> 18

maybe that clears it out for you. cheers

Ok so I am not sure if I actually diagnosed the problem but here is my theory on what was happening(I am not going to mark it as the answer until I give you fine folks a chance to debunk my hypothesis).

I think that since the User object doesn't actually have a password attribute(It has crypted_password and salt attributes instead) the data was getting out of sync somehow. I noticed that even when I would find the user by email and call user.password i would get a nil value in the test, but was getting the correct value from a binding in the controller.

I started by posting to the session controller create action with the new password and that worked but felt pretty dirty. I then looked into how the session controller was actually verifying the password and voila, I fixed my test to use the authenticated? method that the session controller was using. Also don't worry I cleaned up the nested if/elses as well. So my test looks like:

context "User without entitlements" do
      let(:user3) { Factory(:user) }
      let(:user_params_without_entitlement) { {:email => user3.email, :password => "mynewpassword", :password_confirmation => "mynewpassword", publisher_id: user3.publisher_id} }

      before do
        post :create, user_params_without_entitlement
      end

      it "updates the user password for user with no entitlement" do

        User.find_by_email(user3.email).authenticated?("mynewpassword").should be_true
      end

      it "returns a 200 if user password is updated" do
        expect(response.code).to eq('200')
      end
    end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM