17

I would like to add an invite_code requirement for users to sign up. Ie. in addition to requiring them to specify an email/password combo, I want an additional field :invite_code. This is a temporary fix so that non-wanted users cannot login during a given alpha period.

I'm confused since Devise doesn't add controllers. I'm sort of familiar with the concept of virtual attributes, and it strikes me that I could add a :invite_code to the model, and then just hard code a step now where it says invite code must equal 12345 or whatever for now.

Does this make sense with devise authentication? And how do I go approaching this from a proper rails restful approach?

Thank you very much.

Dave
  • 11,392
  • 5
  • 31
  • 42
  • I have added: def invite_code @invite_code end ... which allows the invite_code to be accessible as a virtual attribute, but where should I do the logic for the invite_code must equal "12345" ? – Dave Sep 13 '10 at 22:22

3 Answers3

24

1) A virtual attribute usually needs a setter in addition to a getter.

Easiest way is to add

attr_accessor :invite_code
attr_accessible :invite_code # allow invite_code to be set via mass-assignment
    # See comment by James, below.

to the User model

2) I presume that Devise wants the User model to validate. So you could stop the validation by adding

validates_each :invite_code, :on => :create do |record, attr, value|
    record.errors.add attr, "Please enter correct invite code" unless
      value && value == "12345"
end

NOTE: added :on => :create since the invite_code is only needed for creating the new user, not for updating.

Larry K
  • 47,808
  • 15
  • 87
  • 140
  • That's the best way, because you control the validation message. – François Beausoleil Sep 14 '10 at 01:24
  • for some reason `value` does not hold any value. Maybe this is because I have my new.html.erb file in a different directory from the user directory? – Justin Meltzer Jun 10 '11 at 22:55
  • 2
    @justin-meltzer I had the same issue, add :invite_code to attr_accessible as well (e.g. attr_accessible :email, :password, :password_confirmation, :remember_me, :invite_code) – James Hollingworth Jun 27 '11 at 18:42
  • We used this method but are actually storing the invite_code directly on the user record. We're giving out multiple invite codes to different sources, so this allows us to see where our users came from based on the invite codes. – jfeust Dec 25 '11 at 19:51
  • Rails 4 doesn't have `attr_accessible` any more. How can we do it in Rails 4? Thanks. – Lei Zhao Aug 26 '13 at 06:44
9

Try this: http://github.com/scambra/devise_invitable

It adds support to devise for sending invitations by email (it requires to be authenticated) and accept the invitation setting the password.

It works with Devise >= 4.0 If you want to use devise 3.0.x, you must use 1.2.1 or lower If you want to use devise 3.1.x, you must use 1.3.2 or lower If you want to use devise >= 3.2, you must use 1.6.1 or lower...

gnat
  • 6,213
  • 108
  • 53
  • 73
Jeroen
  • 99
  • 2
  • 1
    Thanks for the link, but I think this does something slightly different - it allows users to invite other users - wheras for now I simply wish to lock-down sign-up of new users altogether unless they have an invitation code I give out. – Dave Sep 14 '10 at 20:19
0

According to the docs, invitable gives you control over who gets to invites others. People cannot distribute invites if there is a "0" setting for invitation_limit.

From the docs:

invitation_limit: The number of invitations users can send. The default value of nil means users can send as many invites as they want, there is no limit for any user, invitation_limit column is not used. A setting of 0 means they can't send invitations. A setting n > 0 means they can send n invitations. You can change invitation_limit column for some users so they can send more or less invitations, even with global invitation_limit = 0.

Fabrizio
  • 7,603
  • 6
  • 44
  • 104
Anne
  • 11
  • 3