views:

175

answers:

3

Hi,

I'd like to generate unique, anonymous usernames when creating an instance of my User model. Ideally, it would be set by default if I don't specify any username.

So for example when I do User.create!() I'd like to have the username column set to 'anonymous123', where 123 is a unique number taken from a sequence (the value of the id column for that instance would be ok).

A: 

Use a before_save filter to set the username before the model is saved, e.g.

class User < ActiveRecord::Base
  before_save :set_anonymous_username

  def set_anonymous_username
    username = "anonymous" + User.find_by_sql("SELECT max(id) FROM users").maxid.to_s if username.nil?
  end
end
workmad3
plain SQL is a pain in the ass if you want to change your database;-)
Yeah, just wasn't aware of a better way to get the last ID from a rails model... and now I do :)
workmad3
A: 

Something like

class User < ActiveRecord::Base
  def initialize
    super
    self.username = "anonymous#{User.last.id + 1}"
  end
end

Will do it when you create a new instance of User, even before it's saved - in case you want to use it in a view pre-creation. You probably want to combine it with something before_save as mentioned above to get the definitive last id in the database at the time of record creation.

zackola
overriding the initialize method of an ActiveRecord object is not recommended, especially if you don't call super, you could look at the after_initialize callback to do this
Peer Allan
gah totally forgot super :) thanks.
zackola
+4  A: 

Combining the examples from a couple of the answers would do it

class User < ActiveRecord::Base
  before_create :set_anonymous_username

  def set_anonymous_username
    username = "anonymous#{User.last.id + 1}" if username.nil?
  end
end

I have used before_create here because I would expect you only to have to set an anonymous username before you create the User for the first time. The before_save will be called every time the model is saved and could be unnecessary overhead, but either will work

Peer Allan
I would also throw in a "validates_uniqueness_of :username" into your User model, just to be sure. It may also pay to check the autogenerated username to ensure there are not any conflicts, or the client may get weird errors and not know why.
askegg