Skip to content

Instantly share code, notes, and snippets.

@johncblandii
Created March 21, 2012 20:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johncblandii/2152420 to your computer and use it in GitHub Desktop.
Save johncblandii/2152420 to your computer and use it in GitHub Desktop.
Need factory to auto-create an invitation
#USER MODEL [just the relevant parts]
has_many :sent_invitations, :class_name=>"Invitation", :foreign_key=>:sender_id
validate :check_for_invitation, :on=>:create
private
def check_for_invitation
errors.add :email, 'has not been invited' unless Gxtended::Invitation.where(:recipient_email=>email).exists?
end
#INVITATION MODEL
class Invitation < ActiveRecord::Base
belongs_to :sender, :class_name => "User"
validates :sender, :presence => true
validates :recipient_email, :presence => true, :uniqueness=>true
validate :recipient_is_not_registered
before_create :generate_token, :only=>[:create]
before_create :set_sent_at, :only=>[:create]
private
def generate_token
self.token = Digest::SHA1.hexdigest([Time.now, rand].join)
end
def recipient_is_not_registered
errors.add :recipient_email, 'is already registered' if Gxtended::User.find_by_email(recipient_email)
end
def set_sent_at
sent_at = Time.now
end
end
#SAMPLE FROM SPECS
before(:each) do
@user = FactoryGirl.create(:user)
@admin = FactoryGirl.create(:admin)
@url = FactoryGirl.create(:url)
end
#FACTORIES
factory :invite, :class => Gxtended::Invitation do
recipient_email "user@gxstream.com"
end
factory :admin, :class => Gxtended::User do
sequence(:username) { |n| "admin#{n}" }
sequence(:email) { |n| "admin#{n}@example.com" }
password 'password'
password_confirmation { |u| u.password }
dob "1980-01-01"
role { Gxtended::Role[:admin] }
end
factory :user, :class => Gxtended::User do
sequence(:username) { |n| "username#{n}" }
sequence(:email) { |n| "user#{n}@example.com" }
password 'password'
password_confirmation { |u| u.password }
dob "1980-01-01"
end
@jwo
Copy link

jwo commented Mar 21, 2012

factory :user do
  after_build { |u| Invitation.new(email: u.email).save(validate: false) }
end

I did validate:false because you have a chicken/egg problem -- the first user in the system has to exist in order for her to be invited, but she'll need another user to invite her.

@johncblandii
Copy link
Author

I was close. I did an after_build with a factory call in there and that kept failing. I'll try the direct model approach.

No validating the invitation is perfect as it is not needed at all anyway until the invitation spec is needed. I'll give this a try momentarily.

@johncblandii
Copy link
Author

Nice. That works. Thx man!

@johncblandii
Copy link
Author

Finished in 22.69 seconds
132 examples, 0 failures

Woot! :-) Since my invitation factory used a static email address, that spec worked just fine as well without interfering with the other invites for admin users. :) Good stuff.

@jwo
Copy link

jwo commented Mar 21, 2012 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment