How can I create unique strings (with no numbers) with factory girl?
Asked Answered
P

4

17

Or is an external gem necessary to generate random and unique usernames maybe?

Here's my current factory:

factory :user_4 do
    sequence(:id) { |n| n }
    sequence(:first_name) { |n| "Gemini" + n.to_s }
    sequence(:last_name) { |n| "Pollux" + n.to_s }
    sequence(:profile_name) { |n| "GeminiPollux" + n.to_s  }
    sequence(:email) { |n| "geminipollus" + n.to_s + "@hotmail.co.uk" }
end

Using the sequence method works for the id, profile_name and email, but my REGEX validations mean that the first name and last name are automatically invalid, because they have a digit in them. Nothing to do with the uniqueness.

So how should I create these unique names?

Pass answered 3/1, 2014 at 13:10 Comment(0)
R
20

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.

Rendarender answered 3/1, 2014 at 13:55 Comment(1)
This answer was very helpful to me but one piece of information that wasn't intuitive to me is that the method definition must not only be outside the factory declaration, it must also be outside the FactoryGirl.define do block as well.Catlike
F
21
factory :user_4 do
  # ...
  sequence(:first_name, 'a') { |n| "Gemini" + n }
  sequence(:last_name, 'a') { |n| "Pollux" + n }
  # ...
end

FactoryGirl's #sequence method accepts a second argument as its starting value. This can be a String, a Fixnum, or something else that supports being incremented by a #next method.

With a starting value of 'a' the sequence will be a, b, c ... z, aa, ab, ac ...

Floris answered 18/7, 2015 at 12:50 Comment(1)
best answer! you can also use 'A' and it will do A, B ... Z, AA, AB ....Typewrite
R
20

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.

Rendarender answered 3/1, 2014 at 13:55 Comment(1)
This answer was very helpful to me but one piece of information that wasn't intuitive to me is that the method definition must not only be outside the factory declaration, it must also be outside the FactoryGirl.define do block as well.Catlike
G
2
factory :user_4 do
  letters = [a,b,c,d]
  sequence(:id) { |n| n }
  sequence(:first_name) { |n| "Gemini" + letters[n] }
  sequence(:last_name) { |n| "Pollux" + letters[n] }
  sequence(:profile_name) { |n| "GeminiPollux" + letters[n]  }
  sequence(:email) { |n| "geminipollus" + letters[n] + "@hotmail.co.uk" }
end

Or simply use ascii conversion, or use Faker gem

Grasso answered 3/1, 2014 at 13:17 Comment(0)
C
0

If you give just a value to sequence, FactoryBot automatically generates a sequence of values by applying #next to that value. Since Ruby's String class prepares #next method, which returns a successor of a string, you can write like the following:

factory :user_4 do
    sequence(:id) { |n| n }
    sequence(:first_name) { "Gemini" }
    sequence(:last_name) { "Pollux" }
    profile_name { "#{first_name} #{last_name}" }
    email { "#{first_name.downcase}#{last_name.downcase}@hotmail.co.uk" }
end

For instance, a sequence of first_name is "Gemini", "Geminj", "Gemink", and so on.

Refs.

Colombo answered 12/3, 2022 at 13:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.