How to Make Id a Random 8 Digit Alphanumeric in Rails

how to make ID a random 8 digit alphanumeric in rails?

You only need to add one attribute to post. The attribute name is permalink.

Try running:

rails g migration add_permalink_to_posts permalink:string
rake db:migrate

You have twoActive Record Callbacks you can choose from: before_save or before_create (review the difference between both). This example is using the before_save callback.

note : for Rails 3.x

class Post < ActiveRecord::Base
attr_accessible :content, :permalink
before_save :make_it_permalink

def make_it_permalink
# this can create a permalink using a random 8-digit alphanumeric
self.permalink = SecureRandom.urlsafe_base64(8)
end

end

urlsafe_base64

And in your routes.rb file:

match "/post/:permalink" => 'posts#show', :as => "show_post"

In posts_controller.rb:

def index
@posts = Post.all
end

def show
@post = Post.find_by_permalink(params[:permalink])
end

Finally, here are the views (index.html.erb):

<% @posts.each do |post| %>
<p><%= truncate(post.content, :length => 300).html_safe %>
<br/><br/>
<%= link_to "Read More...", show_post_path(post.permalink) %></p>
<% end %>

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 to generate unique six digit alpha-numeric code in Ruby

I used this

  require 'sha1'
srand
seed = "--#{rand(10000)}--#{Time.now}--"
Digest::SHA1.hexdigest(seed)[0,6]

How to generate a random string in Ruby This link was useful

Unique random string with alphanumberic required in Ruby

down   = ('a'..'z').to_a
up = ('A'..'Z').to_a
digits = ('0'..'9').to_a
all = down + up + digits
[down.sample, up.sample, digits.sample].
concat(7.times.map { all.sample }).
shuffle.
join
#=> "TioS8TYw0F"

[Edit: The above reflects a misunderstanding of the question. I'll leave it, however. To have no characters appear more than once:

def rnd_str
down = ('a'..'z').to_a
up = ('A'..'Z').to_a
digits = ('0'..'9').to_a
[extract1(down), extract1(up), extract1(digits)].
concat(((down+up+digits).sample(7))).shuffle.join
end

def extract1(arr)
i = arr.size.times.to_a.sample
c = arr[i]
arr.delete_at(i)
c
end

rnd_str #=> "YTLe0WGoa1"
rnd_str #=> "NrBmAnE9bT"

down.sample.shift (etc.) would have been more compact than extract1, but the inefficiency was just too much to bear.

If you do not want to repeat random strings, simply keep a list of the ones you generate. If you generate another that is in the list, discard it and generate another. It's pretty unlikely you'll have to generate any extra ones, however. If, for example, you generate 100 random strings (satisfying the requirement of at least one lowercase letter, uppercase letter and digit), the chances that there will be one or more duplicate strings is about one in 700,000:

t = 107_518_933_731
n = t+1
t = t.to_f
(1.0 - 100.times.reduce(1.0) { |prod,_| prod * (n -= 1)/t }).round(10)
#=> 1.39e-07

where t = C(62,10) and C(62,10) is defined below.

An alternative

There is a really simple way to do this that turns out to be pretty efficient: just sample without replacement until a sample is found that meets the requirement of at least lowercase letter, one uppercase letter and one digit. We can do that as follows:

DOWN   = ('a'..'z').to_a
UP = ('A'..'Z').to_a
DIGITS = ('0'..'9').to_a
ALL = DOWN + UP + DIGITS

def rnd_str
loop do
arr = ALL.sample(10)
break arr.shuffle.join unless (DOWN&&arr).empty? || (UP&&arr).empty? ||
(DIGITS&&arr).empty?
end
end

rnd_str #=> "3jRkHcP7Ge"
rnd_str #=> "B0s81x4Jto

How many samples must we reject, on average, before finding a "good" one? It turns out (see below if you are really, really interested) that the probability of getting a "bad" string (i.e, selecting 10 characters at random from the 62 elements of all, without replacement, that has no lowercase letters, no uppercase letters or no digits, is only about 0.15. (15%). That means that 85% of the time no bad samples will be rejected before a good one is found.

It turns out that the expected number of bad strings that will be sampled, before a good string is sampled, is:

0.15/0.85 =~ 0.17

The following shows how the above probability was derived, should anyone be interested.

Let n_down be the number of ways a sample of 10 can be drawn that has no lowercase letters:

n_down = C(36,10) = 36!/(10!*(36-10)!)

where (the binomial coefficient) C(36,10) equals the number of combinations of 36 "things" that can be "taken" 10 at a time, and equals:

C(36,10) = 36!/(10!*(36-10)!) #=> 254_186_856

Similarly,

n_up = n_down #=> 254_186_856

and

n_digits = C(52,10) #=> 15_820_024_220

We can add these three numbers together to obtain:

n_down + n_up + n_digits #=> 16_328_397_932

This is almost, but not quite, the number of ways to draw 10 characters, without replacement, that contains no lowercase letters characters, uppercase letters or digits. "Not quite" because there is a bit of double-counting going on. The necessary adjustment is as follows:

n_down + n_up + n_digits - 2*C(26,10) - 3
#=> 16_317_774_459

To obtain the probability of drawing a sample of 10 from a population of 62, without replacement, that has no lowercase letter, no uppercase letter or no digit, we divide this number by the total number of ways 10 characters can be drawn from 62 without replacement:

(16_317_774_459.0/c(62,10)).round(2)
#=> 0.15

Generate pseudo random string A-Z, 0-9

Array.new(n){[*"A".."Z", *"0".."9"].sample}.join

Using alpha-numeric slugs instead of ids in routes - Rails

To create a slug, easiest way is to use SecureRandom. You can add something like the following in your model

before_create :generate_slug

private

def generate_slug
begin
self.slug = SecureRandom.urlsafe_base64(8)
end while Organization.exists?(slug: slug)
end

One small caveat here with respect to what you want is that the slug will sometimes contain an underscore or a dash but that should be fine.

irb(main):014:0> SecureRandom.urlsafe_base64(8)
=> "HlHHV_6rN3k"
irb(main):015:0> SecureRandom.urlsafe_base64(8)
=> "naRqT-NmYDU"
irb(main):016:0> SecureRandom.urlsafe_base64(8)
=> "9h04l4jEEsM"

How would i generate a random and unique string in Ruby?

I use this :)

def generate_token(column, length = 64)
begin
self[column] = SecureRandom.urlsafe_base64 length
end while Model.exists?(column => self[column])
end

Replace Model by your model name

Generating a unique and random 6 character long string to represent link in ruby

SecureRandom in ruby uses process id (if available) and current time. You can use the urlsafe_base64(n= 16) class method to generate the sequence you need. According to your requirements I think this is your best bet.

Edit: After a bit of testing, I still think that this approach will generate non-unique keys. The way I solved this problem for barcode generation was:

barcode= barcode_sql_id_hash("#{sql_id}#{keyword}")

Here, your keyword can be time + pid.

Generate Unique Random String With Letters And Numbers In Lower Case

If you are using ruby 1.9.2 you can use SecureRandom:

irb(main):001:0> require 'securerandom'
=> true
irb(main):002:0> SecureRandom.hex(13)
=> "5bbf194bcf8740ae8c9ce49e97"
irb(main):003:0> SecureRandom.hex(15)
=> "d2413503a9618bacfdb1745eafdb0f"
irb(main):004:0> SecureRandom.hex(32)
=> "432e0a359bbf3669e6da610d57ea5d0cd9e2fceb93e7f7989305d89e31073690"


Related Topics



Leave a reply



Submit