With the help of some here, I’m using this code to generate tokens purchased from my app. It loops through depending on how many tokens are ordered, calls a method called create_trackable_token which just generates a unique string to identify the token. I have two questions about this.
1) How can I rewrite it so the particular columns are not vulnerable to mass-assignment? Right now, if I use ‘attr_accessible` on this model, I have to expose the three attributes in this method because it’s assigning them at once. I’d prefer to not do that. The method is already protected, so it can’t be called by an end user.
2) What’s the best way of handling errors? The tokens have to be unique, and right now, I’m not sure what would happen if the create_trackable_token method generates a string that’s already in use. Does ActiveRecord take care of that or do I need to write some error handling into the method?
protected
def create_trackables
return unless self.success
order = Order.find(order_id) #you shouldn't need this line if it has_one :order
1.upto(order.total_tokens) do
Tracker.create!(
:user_id => order.user_id,
:token => Tracker.create_trackable_token,
:order_id => order_id
)
end
end
To handle uniqueness, use a validation on the column, see http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#method-i-validates_uniqueness_of
When creating the token, there are many things to consider, such as how hard do you want it to be to guess (or else do you authenticate a token against something else?) … you could use hashes, such ass MD5, random number, or you could go all out and make a GUID. In any case, you could look for the token before returning from create_trackable_token.
If you want to keep it mass assignment safe you have to do this in a few steps:
t = Tracker.create( :user_id => order.user_id, :order_id => order_id ) t.token = Tracker.create_trackable_token t.save!