2013-03-12 57 views
1

據後我所知,validations are suppose to run before callbacks。不過,我得到的行爲表明否則。具體來說,我有:導軌:驗證被稱爲before_create

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 

測試這個代碼,我一直得到錯誤「此用戶已接到邀請,」即使用戶以前沒有邀請。我最好的猜測是,這種情況正在發生,因爲find_or_create_membership首先運行,從而設置statusinvited。關於正在發生什麼或如何解決這種情況的任何想法?

回答

7

find_or_create_membership運行第一

動作的順序而創造:

before_validation 
after_validation 
before_save 
around_save 
before_create 
after_create 
after_save 
+0

有沒有辦法讓它後來運行?我試着將'after_create'改爲'after_validation',但我得到了同樣的行爲。 – nullnullnull 2013-03-12 20:10:33

+0

我不明白你的代碼清楚,但扭轉你的回調的順序,你可以呼籲'after_create'或'after_save'回調'user_can_be_invited'。解決它,我張貼回調的順序。 – Zippie 2013-03-12 20:15:00

+0

你能看到這個pdf嗎? https://www.edx.org/static/content-berkeley-cs169.2x~2013_Spring/handouts/slides/169.2x-Wk1-LS1.pdf 的順序是從PDF的第2頁。 – Zippie 2013-03-12 20:16:35

1

這個問題實際上從我的控制器莖:

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

這引起了驗證方法被調用invitation.valid?第二次,當然它會發送錯誤消息,然後作爲status有alrea dy已被設置。解決這個問題很簡單。我只是增加了一個:on => :create條件:

validate :user_can_be_invited, :on => :create