Rails 3.2.13 + Faker + Devise + Rolify - ruby-on-rails

I'm building a test app and came across a problem with Faker gem:
I've created Use model with Devise and used Rolify gem to create roles and then later on will use CanCan to limit user's usage permissions.
So, with Faker I've created a file for my rake task:
namespace :db do
desc "Fill dummy DB"
task :populate => :environment do
require "populator"
require "faker"
password = "password"
User.populate 198 do |user|
user.firstname = Faker::Name.first_name
user.lastname = Faker::Name.last_name
user.email = Faker::Internet.email
user.encrypted_password = User.new(:password => password).encrypted_password
user.phone = Faker::PhoneNumber.phone_number
user.address1 = Faker::Address.street_address
user.city = Faker::Address.city
user.state = Faker::Address.state_abbr
user.zip = Faker::Address.zip_code
user.latitude = Faker::Address.latitude
user.longitude = Faker::Address.longitude
end
end
end
This code works and it creates 198 dummy users...but when I looked into my users_roles table - nothing's there, users don't have roles assigned to them. I've been trying to figure out how to assign a role to user through Faker, but no luck.
I've tried adding user.role_id = User.add_role :user , but no luck.
Thank you in advance.

I discourage you from using populator gem. There are three reasons to that:
Populator is no longer maintained, last commit was over two years ago. The official repository still says "Rails 3 support is currently being worked on. Stay tuned." with Rails 4 released over a month ago.
It does not have data validation. It is up to you to ensure you’re adding proper data values. And this may end up really messy.
It's really easy to make it programatically giving you more control over custom cases and therefore making you a better developer =)
You can construct your database populator with user role adding with code below:
namespace :db do
desc "Fill dummy DB"
task :populate => :environment do
198.times do |n|
user = User.new(
firstname: Faker::Name.first_name,
lastname: Faker::Name.last_name,
email: Faker::Internet.email,
password: "password",
phone: Faker::PhoneNumber.phone_number,
address1: Faker::Address.street_address,
city: Faker::Address.city,
state: Faker::Address.state_abbr,
zip: Faker::Address.zip_code,
latitude: Faker::Address.latitude,
longitude: Faker::Address.longitude )
user.add_role :user
user.save
end
end
end
Please note as I:
deleted require statements (at least on my system aren't necessary)
moved password into a block
am adding a role using function, not assignment (=) BEFORE saving a user - not possible using populator
Using this construct, you can make more handy things with the User instance, ex. prevent sending a confirmation email when using Devise's :confirmable by invoking user.skip_confirmation! before saving - what you might find useful.
Consider as well generating emails basing on first_name and last_name already generated by Faker before to have user's name and email inline. To achieve that you may replace
Faker::Internet.email
by
"#{user.first_name}.#{user.last_name}#{n+1}#example.com"
taking advantage of block numerator and therefore creating an unique email.

Related

Rails Faker - How to generate a custom domain email?

Ideally I want to create a fake email based on the Faker generated email, but I want to achieve something like: faker_first_name#mydomain.com. The documentation shows you can do it for the first part but not the actual domain. Is there a way to achieve this?
20.times do
u = User.new(first_name: Faker::Name.first_name,
last_name: Faker::Name.last_name,
email: Faker::Name.first_name"#THISPART.com",
)
u.save
end
Update Dec 2019:
Faker version v2.8.0 introduced the domain support - Release v2.8.0
Now, It is possible to pass the domain while creating the email address.
Following are the possible options:
Faker::Internet.email #=> "eliza#mann.net"
Faker::Internet.email(name: 'Nancy') #=> "nancy#terry.biz"
Faker::Internet.email(name: 'Janelle Santiago', separators: '+') #=> janelle+santiago#becker.com"
Faker::Internet.email(domain: 'example.com') #=> alice#example.com"
Note: Above code sample is from the faker documentation
Old Answer:
Well there is no such provision to pass domain name to the method
But, you can make use of Faker::Internet.user_name
User.new(
first_name: Faker::Name.first_name,
last_name: Faker::Name.last_name,
email: "#{Faker::Internet.user_name}#customdomain.com"
)
I think you just missed the string concat: +
:006 > Faker::Name.first_name+"#THISPART.com"
=> "Irving#THISPART.com"
And if you meant keeping the same name, save it before:
fn = Faker::Name.first_name
sn = Faker::Name.last_name
u = User.create(
:forename => fn,
:surname => sn,
:email => "#{fn}.#{sn}#yourdomain.net",
Faker::Name.first_name will always generate a new random value.
Recent versions of Faker has a built in support for custom email subdomains.
Faker::Internet.email(domain: 'customdomain.com')

Have access to multiple databases [duplicate]

In our program, each customer gets their own database. We e-mail them a link that connects them to their database. The link contains a GUID that lets the program know which database to connect to.
How do I dynamically and programatically connect ActiveRecord to the right db?
You can also do this easily without hardcoding anything and run migrations automatically:
customer = CustomerModel.find(id)
spec = CustomerModel.configurations[RAILS_ENV]
new_spec = spec.clone
new_spec["database"] = customer.database_name
ActiveRecord::Base.establish_connection(new_spec)
ActiveRecord::Migrator.migrate("db/migrate_data/", nil)
I find it useful to re-establish the old connection on a particular model afterwards:
CustomerModel.establish_connection(spec)
you can change the connection to ActiveRecord at any time by calling ActiveRecord::Base.establish_connection(...)
IE:
ActiveRecord::Base.establish_connection({:adapter => "mysql", :database => new_name, :host => "olddev",
:username => "root", :password => "password" })
It's been a while since this question has been created, but I have to say that there is another way too:
conn_config = ActiveRecord::Base.connection_config
conn_config[:database] = new_database
ActiveRecord::Base.establish_connection conn_config
class Database
def self.development!
ActiveRecord::Base.establish_connection(:development)
end
def self.production!
ActiveRecord::Base.establish_connection(ENV['PRODUCTION_DATABASE'])
end
def self.staging!
ActiveRecord::Base.establish_connection(ENV['STAGING_DATABASE'])
end
end
And in .env (with dotenv-rails gem for instance):
PRODUCTION_DATABASE=postgres://...
STAGING_DATABASE=postgres://...
And now you can:
Database.development!
User.count
Database.production!
User.count
Database.staging!
User.count
# etc.

Create object with relationship in Salesforce with Restforce using Rails

I use Ruby on Rails 4.2.5 with the Restforce gem for Salesforce API. I create a Contact in my controller :
class CandidateFormController < ApplicationController
def index
client = Restforce.new(
:username => ENV['SALESFORCE_USERNAME'],
:password => ENV['SALESFORCE_MDP'],
:security_token => ENV['SALESFORCE_TOKEN'],
:client_id => ENV['SALESFORCE_APIKEY'],
:client_secret => ENV['SALESFORCE_SECRET'],
)
new_client = client.create('Contact', FirstName: #first_name,
LastName: #last_name,
Email: #email,
MobilePhone: #telephone,
Description: #champ_libre,
Profil_LinkedIN__c: #linkedin
)
end
end
I have a relationship between two of my tables.
Candidate is associated to Opportunity (a job offer if you prefer), and the restforce documentation doesn't explain how to create a new entry with a relation between two elements, or if it does I am not enough experimented to have understand how am I supposed to do so.
I have not enough credit to post screenshots, but if this is necesseray I can use imgur or something like that.
P.S : I already see this post on the subject, but that didn't help me at all.
Well, after another hour of research I finally find how to create relationship in salesforce.
My code looks like this now :
class CandidateFormController < ApplicationController
def index
client = Restforce.new(
:username => ENV['SALESFORCE_USERNAME'],
:password => ENV['SALESFORCE_MDP'],
:security_token => ENV['SALESFORCE_TOKEN'],
:client_id => ENV['SALESFORCE_APIKEY'],
:client_secret => ENV['SALESFORCE_SECRET'],
)
new_client = client.create('Contact', FirstName: #first_name,
LastName: #last_name,
Email: #email,
MobilePhone: #telephone,
Description: #champ_libre,
Profil_LinkedIN__c: #linkedin
)
new_candidature = client.create(
'Candidatures__c',
Candidats__c: "someId",
Offredemploi__c: new_client
)
end
end
In my case, I wanted to create a relationship between an Opportunity and a Contact (A job offer and a Candidate).
I look more into fields that already was created and filled for Opportunity and Contact in my salesforce account, and find out that there were no field that was corresponding to the relationship I was looking for.
I discover than in salesforce, there are objects that exist just for the junction between two objects, and they are called "Junction Object" (pretty obvious, but not easy to find).
You just have to create a new salesforce object with create() after the creation of your first element (a Contact for me) and create the junction object with the good type (for me it was Candidatures__c), and specify the two relationships.
In my own code I create an new Candidature__c, I specify the Id of the job offer (the Candidats__c id) and the Id of the candidate in Offredemploi__c with the Id I create some lines above.
Hope it will helps.

Faker is producing duplicate data when used in factory_girl

I'm trying to populate some fake data into a factory using the Faker gem:
Factory.define :user do |user|
user.first_name Faker::Name::first_name
user.last_name Faker::Name::last_name
user.sequence(:email) {|n| "user#{n}#blow.com" }
end
However while I expect this to produce users who have different first_name and last_names, each one is the same:
>> Factory(:user)
=> #<User id: 16, email: "user7#blow.com", created_at: "2011-03-18 18:29:33",
updated_at: "2011-03-18 18:29:33", first_name: "Bailey", last_name: "Durgan">
>> Factory(:user)
=> #<User id: 17, email: "user8#blow.com", created_at: "2011-03-18 18:29:39",
updated_at: "2011-03-18 18:29:39", first_name: "Bailey", last_name: "Durgan">
How can I get the Faker gem to generate new names for each users and not just reuse the original ones?
Factory.define :user do |user|
user.first_name { Faker::Name::first_name }
user.last_name { Faker::Name::last_name }
user.sequence(:email) {|n| "user#{n}#blow.com" }
end
Try putting brackets around the fakers. see this link
Note that Faker may still be providing duplicate data due to the limited amount of fake data available.
For simple testing purposes and to get by uniqueness validations, I've used the following:
sequence(:first_name) {|n| Faker::Name::first_name + " (#{n})"}
sequence(:last_name) {|n| Faker::Name::last_name + " (#{n})"}
For the sake of preserving the correct answer, here it is translocated from the blog, I take no credit for the answer.
If you use the code below, faker will not churn out unique names
Factory.define :user do |u|
u.first_name Faker::Name.first_name
u.last_name Faker::Name.last_name
end
However putting curly braces around faker makes it work!
Factory.define :user do |u|
u.first_name { Faker::Name.first_name }
u.last_name { Faker::Name.last_name }
end
To explain why, the first example is producing the same names. It's only evaluating once. The second example evaluates every time the factory is used.
This is due to the {} providing lazy evaluation. Essentially they are providing a proc/lambda with the Faker call as their return value.
A (less efficient) alternative to using sequences when you have a uniqueness validation on an attribute is to check whether a proposed value already exists and keep trying new ones until it's unique:
FactoryGirl.define do
factory :company do
name do
loop do
possible_name = Faker::Company.name
break possible_name unless Company.exists?(name: possible_name)
end
end
end
end

How can I dynamically change the Active Record database for all models in Ruby on Rails?

In our program, each customer gets their own database. We e-mail them a link that connects them to their database. The link contains a GUID that lets the program know which database to connect to.
How do I dynamically and programatically connect ActiveRecord to the right db?
You can also do this easily without hardcoding anything and run migrations automatically:
customer = CustomerModel.find(id)
spec = CustomerModel.configurations[RAILS_ENV]
new_spec = spec.clone
new_spec["database"] = customer.database_name
ActiveRecord::Base.establish_connection(new_spec)
ActiveRecord::Migrator.migrate("db/migrate_data/", nil)
I find it useful to re-establish the old connection on a particular model afterwards:
CustomerModel.establish_connection(spec)
you can change the connection to ActiveRecord at any time by calling ActiveRecord::Base.establish_connection(...)
IE:
ActiveRecord::Base.establish_connection({:adapter => "mysql", :database => new_name, :host => "olddev",
:username => "root", :password => "password" })
It's been a while since this question has been created, but I have to say that there is another way too:
conn_config = ActiveRecord::Base.connection_config
conn_config[:database] = new_database
ActiveRecord::Base.establish_connection conn_config
class Database
def self.development!
ActiveRecord::Base.establish_connection(:development)
end
def self.production!
ActiveRecord::Base.establish_connection(ENV['PRODUCTION_DATABASE'])
end
def self.staging!
ActiveRecord::Base.establish_connection(ENV['STAGING_DATABASE'])
end
end
And in .env (with dotenv-rails gem for instance):
PRODUCTION_DATABASE=postgres://...
STAGING_DATABASE=postgres://...
And now you can:
Database.development!
User.count
Database.production!
User.count
Database.staging!
User.count
# etc.

Resources