Creating devise users from a CSV file - Rails - PG - ruby-on-rails

I have been given a CSV file that contains emails and passwords.
My task is to go through this CSV file and create users using the devise gem.
You will probably wonder why I hace been given peoples emails and passwords (I am as well), but I've been told not to worry about it.
My csv file looks like this:
Email,Password,Password_confirmation,,
email1#email.com ,password1,password1,,
email2#email.com ,password2,password2,,
email3#email.com ,password3,password3,,
I wrote the following code in my seeds.rb file:
require 'csv'
CSV.foreach("db/fixtures/users.csv", :col_sep => ",", :headers => true) do |row|
User.create(email: row['email'], password: row['password'], password_confirmation: row['password_confirmation'])
end
I run rails db:seed to create the users, but nothing happens, no error messaged either.
Any support would be welcomed.

First of all, it's a really bad idea to put that file with actual passwords under version control and to import it in seeds.rb. Would be much better to add a rake task for that purpose accepting csv file path as an argument and perform it once in a suitable environment.
About the code, the headers in CSV import are case sensitive, so it would work if you get the row value via row['Email'], row['Password'] etc.
Also, make sure that filling in those fields are enough to save the user, there may be some other required fields in your particular model.

Related

Rails: Background task for regular feed

I have a new requirement for an existing app and I wanted to ask other developers how to go about developing it. I want to export CSV every 2 days and provide my sales team feeds which they use to bulk import on a designated data storage location, say google drive. they can then check the file and do uploads etc.
I want to run a Heroku scheduler which runs every 2 days and exports data from the app, save the file in a specific format with a specific header to that storage.
I know that I can write a class method which generates the format, use strategy pattern to get a specific header and provide it using respond_to and give a format csv so a user can access that file through a URL but how can I write a rake task which creates the file and uploads it to the specific location I specify ?
Will really appreciate any direction
In Rails rake tasks are usually stored in lib/tasks and have .rake extension. For the CSV part, you can use the CSV API of Ruby. After generating a CSV you can save it locally or upload it to any service you want (e.g. S3, Google Drive, etc). For example, take S3:
# lib/tasks/csv_tasks.rake
namespace :csv do
desc 'Generates new feed'
task :feed do
client = Aws::S3::Client.new(region: 'eu-west-1',
access_key_id: 'access_key_id',
secret_access_key: 'secret_access_key')
feed_csv = CSV.generate do |csv|
# headers
csv << [:first_name, :last_name]
# CSV rows
Employee.find_each do |employee|
csv << [employee.first_name, employee.last_name]
end
end
client.put_object({
body: feed_csv,
bucket: 'my_bucket',
key: 'feed.csv',
})
end
end
Then in Heroku scheduler use the defined task rake csv:feed
You might also consider having a model for your files in order to save their paths and then display them easily in your application.
I advise you to save your S3 or other credentials in the secrets.yml file or the credentials file (Rails 5.2+). To use the AWS SDK for Ruby, add this to your Gemfile:
gem 'aws-sdk', '~> 3'
And require it in the rake task, if needed. For more info about how to work with S3 and ruby, read here.

How to control RoR I18n texts stored in database?

I'm using the I18n Gem from Sven Fuchs in my Ruby on Rails 3.2 Application and while the gem works great I came across a situation, which I don't know the solution to:
I have a seed file, which contains the basic translation for my MVC's and is seeded, when I install my application on a new machine. The problem is that when one of these translations changes, I have to go to my seed file, edit it, delete in the database and reseed it. Which is problem not the best way to do this.
Furthermore, my application can create complete MVC's on the fly, which of course need translations as well. These translations get only stored in the database. But it would be nice to store them in a real file, keep them under version control and import or export them if I need to.
So, basically what I'm looking for, is an intelligent connection between the translations in my database and the ones in my files. So I can populate one from the other or vica verca and keep them in sync.
And also I looked at solutions like Globalize3 or localeapp, but they don't seem to fit.
Summarized, what I have is:
The I18n Gem from Sven Fuchs with a Backend I created myself
A Seed File which changes sometimes and has to be edited manually but seeds the basic translations
A database which contains translations that are created on the fly and are not under version control, nor stored in some file
What I want:
A sync between translations in my seed file and my database
A way to put my translations under version control
I'm sure I can't be the only one who needs this...
Thanks in regards!
Here is how I solved a problem closer to the question asked:
task :task_name => [:environment] do
file = "db/file_name.txt"
counter = 0
CSV.foreach(file, :headers => true, :col_sep => "^", :quote_char => "~") do |row|
identifier = row[0].to_i
model_name = ModelName.find_or_create_by_identifier(identifier)
I18n.locale = row[1]
model_name.name = row[3]
model_name.save!
end
end
Note that identifier needs to be a unique identifier that doesn't change and exists in the file and in the database. In this example, the columns are separated by "^" and quores are "~"
As #tigrish said in the comments, it is not a good idea to insert in the file and in the database, so it is important to restrict this.
These links may also help:
http://railscasts.com/episodes/396-importing-csv-and-excel
http://jasonseifer.com/2010/04/06/rake-tutorial
As the question is a little old, I hope it can help somebody else.

How to set default data in a table in rails?

I have a table that I'm going to store units of measurements in and the corresponding category. For example, "cups, volume" and "ounce, mass". I only have about 12 measurements I care about, and I want them to be in the database without manually entering them because anytime I want to deploy it or move the code somewhere, I want this to recreate.
So, I figure the best way to do this is to create a csv file with them, and then use rake db:seed. But I've never done this before so can someone guide me as to how to create this csv, and how to write the seeds.rb file to generate that? Is this the right way to do it?
SOLUTION:
#db/seeds.rb
require 'open-uri'
#Supply all the units of measurement to be used
Unit.delete_all
open("db/seeds/measurements.csv") do |measurements|
measurements.read.each_line do |measurement|
unit, uof = measurement.chomp.split(",")
Unit.create!(:name => unit, :unit_of => uof)
end
end
Just write the code you'd use to generate them manually and put it in the seeds.rb. You can use normal ruby in that file; so either just write plain create's or load a csv you store in, e.g. db/seeds/measurements.csv. To get the path to that file, use Rails.root.join("db/seeds/measurements.csv").
Example:
File.open(Rails.root.join("db/seeds/measurements.csv")) do |f|
# use f here
end
There's a file called seeds.rb in db directory.
You can add your default data in it and when you execute rake db:seed, that data will be populated in your database.
Here's an example of how you can add seeds to it.
product_types = ProductType.create([
{:name => 'clock',:organisation_id => 1}
])

importing excel to sqlite in rails application

I am making an application in Ruby on Rails which will ask users multiple choice questions. I want to upload questions to the database from an excel file. How can I do it?
Save the Excel spreadsheet as a CSV file then use a CSV parser, perhaps in a rake file:
In lib/taks/import.rake:
require 'fastercsv'
namespace :import => :environment do
task :questions do
FasterCSV.foreach("path/to/file.csv") do |row|
q = Question.create(:question=>row[0], etc...)
PossibleAnswer.create(:question=>q, :answer=>row[1], etc....) #providing PossibleAnswer belongs_to Question
end
end
end
Then run "rake import:questions"
You could use the spreadsheet gem to read in the data from an excel file:
http://rubygems.org/gems/spreadsheet
This is most useful if you want to allow users to upload their own excel documents, to import some questions, or if you want users to be able to download questions in excel file format.
If you just want to do a one-off import of some data i would go with Yule's idea and just do it via csv which is much easier to get to grips with.

Is there any gem can dump the data from and to yml files?

I'm find such a gem a whole day, but not find a good one. I want to write one, but I'm not able to do it.
The data in my database may be English text, which will be dump to a yml file with plain text. And some are non-English text, which will be binary type.
And both of them may have such code:
<% xxx %>
When I use rake db:fixtures:load to load them into database, error may occur: method xxx not found.
I wan't to find a good gem can handle this problem. Thank for any help
UPDATE
I have gave up finding such a gem. At first, I think it's a easy task, but now, after some researchings, I have to say, it's much harder than I expected.
The reason you are having problems is because the Fixture loader will pass your fixture through erb before loading the data. This means that if you have <% xxx %> in your yaml file then Rails will see that as erb and try to run a method called xxx.
There does not seem to be an easy way to turn off erb processing of fixtures. I have tried replacing the fixtures with CSV fixtures and this still does ERB pre-processing.
Without a simple answer I have to ask the question Why do you have these strings in your file?
Do you want them to be expanded by erb?
Err...I'm not sure if you actually need a gem for this? Rails natively can turn any model into YAML.
Let's say you have a model called "Objects". You could hit a route that looks like:
/objects.yaml
and you would get a giant text file of all your Objects in YAML form.
Of course, you would want to have something like:
respond_to do |format|
format.yaml {render :yaml => #objects}
end
in your restful controller.
If you'd rather not hit a route to do this, you can always do
#yaml = []
#objects.each do |object|
#yaml.push object.to_yaml
end
anywhere in ruby, which will give you an array of yaml objects, that you can then write to a file at your leisure.
I imagine that if rails itself is generating the yaml, then it would be able to then later load it as a fixture?

Resources