memorable name generator gem for ruby
You can use randexp gem. It's use the dictionnary from your OS ( UNIX only )
with randexp gem you can do something like :
/[:word:]-[:word:]-\d+/.gen
and have like heroku naming.
If your server has no dict library install you can try faker or Lorem
but really much limitated.
Word generator for ruby testing
Check out Faker. For example,
ruby-1.8.7-p302 > Faker::Lorem.sentence
=> "Enim molestiae incidunt rem ipsum perferendis beatae excepturi tenetur."
ruby-1.8.7-p302 > Faker::Name.name
=> "Agnes Hand II"
Best way to write initializers on a gem
This is untested, but I think you can do:
module MyGem
class Railtie < Rails::Railtie
config.to_prepare do
JbuilderTemplate.class_eval do
def custom_cache!(resource, name, &block)
fragment_cache_key = ::MyGem::Logic.cache_key(name, resource)
options = { expires_in: 1.hour }
cache!(fragment_cache_key, options, &block)
end
end
end
end
end
See here (http://api.rubyonrails.org/classes/Rails/Railtie.html#class-Rails::Railtie-label-Configuration) for more information about the config.to_prepare
block.
How to generate a random string in Ruby
(0...8).map { (65 + rand(26)).chr }.join
I spend too much time golfing.
(0...50).map { ('a'..'z').to_a[rand(26)] }.join
And a last one that's even more confusing, but more flexible and wastes fewer cycles:
o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
string = (0...50).map { o[rand(o.length)] }.join
If you want to generate some random text then use the following:
50.times.map { (0...(rand(10))).map { ('a'..'z').to_a[rand(26)] }.join }.join(" ")
this code generates 50 random word string with words length less than 10 characters and then join with space
How can I create unique strings (with no numbers) with factory girl?
There are infinite possible solutions to generate a random string without relying on third party gems.
Here's one
('a'..'z').to_a.shuffle.join
# => "sugrjtyoiqlbxkzcfnawdhpevm"
Example
factory :user_4 do
sequence(:id) { |n| n }
first_name { "Gemini" + random_name }
# ...
end
def random_name
('a'..'z').to_a.shuffle.join
end
If the random factor is too low, you can increase the complexity.
Generating simple passwords based on dictionary words in Rails
Building on my comment - Use the forgery gem like here: https://stackoverflow.com/a/7516358/1081340 but modified like so (a colour and a streetname or any combination you want)
[Forgery::Basic.color, Forgery::Address.street_name.split(" ").first].join("").downcase
which gives you passwords like
=> orangenobel
=> fusciamanley
=> violetvillage
The advantage is you have control on two names and dont have to worry about a random dictionary generator generating passwords like spitface
or headache
(or something NSFW :), not a good problem to have) and it gives a nice heroku url feel to it.
For random dictionary words - use http://rubygems.org/gems/random-word or https://github.com/benburkert/randexp to generate two words and then attach to each other. But then you might have to filter out bad seeds :)
How can I programmatically generate Heroku-like subdomain names?
Engineer at the Heroku API team here: we went with the simplest approach to generate app names, which is basically what you suggested: keep arrays of adjectives and nouns in memory, pick an element from each at random and combine it with a random number from 1000 to 9999.
Not the most thrilling code I've written, but it's interesting to see what we had to do in order to scale this:
At first we were picking a name, trying to
INSERT
and then rescuing the uniqueness constraint error to pick a different name. This worked fine while we had a large pool of names (and a not-so-large set of apps using them), but at a certain scale we started to notice a lot of collisions during name generation.To make it more resilient we decided to pick several names and check which ones are still available with a single query. We obviously still need to check for errors and retry because of race conditions, but with so many apps in the table this is clearly more effective.
It also has the added benefit of providing an easy hook for us to get an alert if our name pool is low (eg: if 1/3 of the random names are taken, send an alert).
The first time we had issues with collisions we just radically increased the size of our name pool by going from 2 digits to 4. With 61 adjectives and 74 nouns this took us from ~400k to ~40mi names (
61 * 74 * 8999
).But by the time we were running 2 million apps we started receiving collision alerts again, and at a much higher rate than expected: About half of the names were colliding, what made no sense considering our pool size and amount of apps running.
The culprit as you might have guessed is that
rand
is a pretty bad pseudorandom number generator. Picking random elements and numbers withSecureRandom
instead radically lowered the amount of collisions, making it match what we expected in first place.
With so much work going to scale this approach we had to ask whether there's a better way to generate names in first place. Some of the ideas discussed were:
Make the name generation a function of the application id. This would be much faster and avoid the issue with collisions entirely, but on the downside it would waste a lot of names with deleted apps (and damn, we have A LOT of apps being created and deleted shortly after as part of different integration tests).
Another option to make name generation deterministic is to have the pool of available names in the database. This would make it easy to do things like only reusing a name 2 weeks after the app was deleted.
Excited to see what we'll do next time the collision alert triggers!
Hope this helps anyone working on friendly name generation out there.
Related Topics
How to Get a Substring from Position N to the Last Char in Ruby
Ruby Operator Overloading Question
Trouble Downgrading Ruby on Os X Mavericks
Installing MySQL2 Gem for Ruby on Rails 3.1.0
Ruby Code Beautification, Split Long Instructions on Multiple Lines
Changing Value of Ruby Variables/References
How to Test Instance Variable Was Instantiated in Controller with Rspec
How to Pass <Arguments> to Irb If I Don't Specify <Programfile>
How to Print Information About a Net:Httprequest for Debug Purposes
Does Concurrency Happen Even When Only One Thread Is in a Thread Pool
How to Push Keys and Values into an Empty Hash W/ Ruby
How to Enable Ssl for a Standalone Sinatra App
Ruby on Rails: Conditionally Display a Partial
Ruby on Rails Named Scope Implementation
Rails Pass Params/Arguments to Activerecord Callback Function