0

I'm not sure if I'm supposed to do this transaction in controller or model since I have to calculate and change other user's column value.

In my understanding, stating in model is only for changing the value of itself(user-self here)

Existing user(ID:1367) can send this url to his friends as an invitation.

http://example.com/users/sign_up?invitation=1367

Then Users table has hidden column called invitation.

and This is procedure how it works that I want.

  1. His friend input information to sign up.

  2. He hits submit button then hidden field 'invitation' will be also sent to form.

  3. 1367 will be set in the column called 'invitation' of the record.

  4. He will receive confirmation mail, and when he clicks on the link, I'd like to add this transaction, and execute only once for his account.
    Of course, this shouldn't be executed when the existing user tried to re-activate.
    Only for the first confirmation for the new user.

code

@user = User.find_by_invitation(current_user.invitation)
@user.friends = @user.friends + 1
@user.save

I already have registration controller that helps adding extra transaction to Devise.
Now I want to know how I can implement this procedure to my app.

Should it be something like this?

registrations_controller.rb

def after_????????
    if @user = User.find_by_invitation(current_user.invitation)
        @user.friends = @user.friends + 1
        @user.save
    end
end
cat
  • 749
  • 10
  • 22

1 Answers1

0

I would use an after_create callback on User, but only call the callback if the user was invited by a friend (e.g. that hidden field on the form is set). So, something like:

class User << ActiveRecord::Base

  attr_accessor :inviter_user_id

  after_create :increment_inviter_user, :if => lambda {|u| u.inviter_user_id.present?}

  private

  def increment_inviter_user
    inviter = User.find(inviter_user_id)

    return false unless inviter.present?

    inviter.friends += 1

    inviter.save
  end

end

Then in your controller on signup for the new user, you would set the inviter_user_id accessor on the new user to the hidden field value.

class UserController << ApplicationController

  def signup
    @user = User.new(user_permitted_params) # or whatever logic you use to create a user

    @user.inviter_user_id = params[:invitation] if params[:invitation].present?

    if @user.save
      ...
    end
  end

end

Fair warning: I haven't tested this - but this is the approach I'd take.

CDub
  • 13,146
  • 4
  • 51
  • 68
  • 1
    Thanks for beautiful solution. But my question was firing transaction only when after confirmation not after create. – cat Nov 10 '13 at 04:37
  • 1
    You could check to see if `confirmation` has changed on the new `User`: http://stackoverflow.com/questions/4558463/rails-devise-after-confirmation – CDub Nov 10 '13 at 18:26