nullnullnull
nullnullnull

Reputation: 8189

Rails: Validation Being Called After before_create

As far as I can tell, validations are suppose to run before callbacks. I'm getting behavior that suggests otherwise, though. Specifically, I have:

class User::GroupInvitation < ActiveRecord::Base

  validate :user_can_be_invited

  before_create :find_or_create_membership

  private

    def user_can_be_invited
      user_membership = User::Membership.where(:group_id => self.group_id, :user_id => self.invitee_id).first
      if user_membership.present?
        case user_membership.status
        when "invited"
          errors[:base] << I18n.t("user.group_invitations.create.this_user_is_already_invited")
        end
      end
    end

    def find_or_create_membership
      user_membership = User::Membership.where(:group_id => self.group_id, :user_id => self.invitee_id).first_or_create(:status => "invited")
      user_membership.update_column(:status, "invited") unless user_membership.new_record?
      self.user_membership_id = user_membership.id
    end
end

Testing this code, I consistently get the error "This user is already invited," even when the user hasn't been previously invited. My best guess is that this is happening because find_or_create_membership is running first, thereby setting status to invited. Any ideas about what's going on or how to resolve the situation?

Upvotes: 3

Views: 9392

Answers (2)

nullnullnull
nullnullnull

Reputation: 8189

The problem actually stems from my controller:

invitation = User::GroupInvitation.create(params[:user_group_invitation])
if invitation.valid?
  . . . .
else
  . . . .
end

This caused the validation method to get called a second time during invitation.valid?, and of course it would send the error message then as a status had already been set. Fixing the problem was easy. I simply added an :on => :create condition:

validate :user_can_be_invited, :on => :create

Upvotes: 2

Zippie
Zippie

Reputation: 6088

find_or_create_membership is running first

The order of the actions while creating:

before_validation
after_validation
before_save
around_save
before_create
after_create
after_save

Upvotes: 11

Related Questions