rails read the file and store the database - ruby-on-rails

i saved .rb file in app/component/text.rb. i want to read and store the database.
in that file has 5 rows and my table also have 5 rows.i want to save line by line.you can understand my question.i use mysql database.
please help me....
thanks,
kingston.s

I missed the rails- and ruby-version, the operating system you use and a clear problem description...anyway
Assuming that you meant your database would have 5 fields and you want to read and write a record to a file:
Assuming the file will contain a record for the model "Apple "with the fields id, title and description.
Read new Apple from file:
indexes = [:id, :title, :desc].reverse # be careful the data will be saved reverse because pop takes the last element first
record_params = {}
handle = File.open("Apple.record","r")
handle.lines.each do |line|
record_params[indexes.pop]=line.chomp #use chomp to get rid of the trailing \n
end
handle.close
Apple.create!(record_params)
Write Apple with id 7 to a File
indexes = [:id, :title, :desc]
record = Apple.find(7)
to_save = indexes.map{|i| record.send i}
handle = File.open("Apple.record","w")
handle.write(to_save.join("\n"))
handle.close
Beware to escape the linebreaks in your data if there are any possible..
Anyway it would be much easier to use YAML:
#write the first apple to the file
handle = File.open("Apple.record", "w")
handle = Apple.first.to_yaml
handle.close
#read the file to a new record
record_params = YAML.load File.read("Apple.record")
Apple.create!(record_params)
All this worked in Rails 3, but remember, that you are saving the id as well, therefore saving and loading will cause the id to change, because a record with the given id already existed.

Related

How to create a hash for all records created by a user?

In our Rails app, the user (or we on his behalf) load some data or even insert it manually using a crud.
After this step the user must validate all the configuration (the data) and "accept and agree" that it's all correct.
On a given day, the application will execute some tasks according the configuration.
Today, we already have a "freeze" flag, where we can prevent changes in the data, so the user cannot mess the things up...
But we also would like to do something like hash the data and say something like "your config is frozen and the hash is 34FE00...".
This would give the user a certain that the system is running with the configuration he approved.
How can we do that? There are 7 or 8 tables. The total of records created would be around 2k or 3k.
How to hash the data to detect changes after the approval? How would you do that?
I'm thinking about doing a find_by_user in each table, loop all records and use some fields (or all) to build a string and hash it at the end of the current loop.
After loop all tables, I would have 8 hash strings and would concatenate and hash them in a final hash.
How does it looks like? Any ideas?
Here's a possible implementation. Just define object as an Array of all the stuff you'd like to hash :
require 'digest/md5'
def validation_hash(object, len = 16)
Digest::MD5.hexdigest(object.to_json)[0,len]
end
puts validation_hash([Actor.first,Movie.first(5)])
# => 94eba93c0a8e92f8
# After changing a single character in the first Actors's biography :
# => 35f342d915d6be4e

How to map data imported via xlsx with no headers in rails 4

I want to add an import function for the users of my rails app, however the files that they will import won't have a header and the interesting data will start at row 8. In the rows I only need 2 fields
Here is an example of a line in the xlsx file :
751,"01/17/2015","11:17:32","60","TDFSRDSK","2","10","-1","0","3","","26","3","","","1","0"
I'll only need the date and the number in 4th field (60) and add them to an SQL table
I have a problem with the mapping and how to do it. I've tried to do it based on the railscast tutorial and roo doc but I can't manage to make it work.
def self.import(file)
xlsx = Roo::Excelx.new(file)
xlsx.each_row do |row|
date = row[2]
value = row[4]
user_id = current_user.id
product.create(:date => date, :valeur => value, :user_id => user_id)
end
end
And the error I get :
no implicit conversion of ActionDispatch::Http::UploadedFile into String
I'm really new to rails/ruby so I'm not even sure the mapping code is supposed to be like that.
It seems like you need to read the contents of the uploaded file into a String object first:
xlsx = Roo::Excelx.new(file.read)
You can refer to the relevant Rails guide for details on how this works.

Saving form results to a CSV - Rails

I'm trying to save the results of a survey to a csv file, so every time the survey is completed it adds a new line to the file. I have code that exports database rows to a csv and lets you download it, but i don't know how to incorporate saving the survey to begin with, or if this is even possible? I have a csv file set up with the correct headers.
When your create function is called (the action in controller where form’s submit is directed to; create on REST controllers), you can just add some custom logic to there to convert the data from form into csv structure you want.
Ruby has CSV module builtin, which can be used to both read and write CSV files.
So you want something like following
require "csv"
CSV.open "output.csv", "a+" do |csv|
# example logic from another script how to populate the file
times.each do |key, value|
csv << [ key, value ]
end
end
You just need to define structure of rows how you want, this example throws two columns per row.
EDIT: a+ makes file to be written from the end (new rows) rather than original w+ that truncates the files.
A possible solution could be to use a logger. In your application controller:
def surveys
##surveys_log ||= Logger.new("#{Rails.root}/log/surveys.log")
end
Anywhere where you would like to log the survey:
surveys.info #survey.to_csv # you'll need to implement "to_csv" yourself
Which will result in a surveys.log in your log/ folder.

Using and Editing Class Variables in Ruby?

So I've done a couple of days worth of research on the matter, and the general consensus is that there isn't one. So I was hoping for an answer more specific to my situation...
I'm using Rails to import a file into a database. Everything is working regarding the import, but I'm wanting to give the database itself an attribute, not just every entry. I'm creating a hash of the file, and I figured it'd be easiest to just assign it to the database (or the class).
I've created a class called Issue (and thus an 'issues' database) with each entry having a couple of attributes. I was wanting to figure out a way to add a class variable (at least, that's what I think is the best option) to Issue to simply store the hash. I've written a rake to import the file, iff the new file is different than the previous file imported (read, if the hash's are different).
desc "Parses a CSV file into the 'issues' database"
task :issues, [:file] => :environment do |t, args|
md5 = Digest::MD5.hexdigest(args[:file])
puts "1: Issue.md5 = #{Issue.md5}"
if md5 != Issue.md5
Issue.destroy_all()
#import new csv file
CSV.foreach(args[:file]) do |row|
issue = {
#various attributes to be columns...
}
Issue.create(issue)
end #end foreach loop
Issue.md5 = md5
puts "2: Issue.md5 = #{Issue.md5}"
end #end if statement
end #end task
And my model is as follows:
class Issue < ActiveRecord::Base
attr_accessible :md5
##md5 = 5
def self.md5
##md5
end
def self.md5=(newmd5)
##md5 = newmd5
end
attr_accessible #various database-entry attributes
end
I've tried various different ways to write my model, but it all comes down to this. Whatever I set the ##md5 in my model, becomes a permanent change, almost like a constant. If I change this value here, and refresh my database, the change is noted immediately. If I go into rails console and do:
Issue.md5 # => 5
Issue.md5 = 123 # => 123
Issue.md5 # => 123
But this change isn't committed to anything. As soon as I exit the console, things return to "5" again. It's almost like I need a .save method for my class.
Also, in the rake file, you see I have two print statements, printing out Issue.md5 before and after the parse. The first prints out "5" and the second prints out the new, correct hash. So Ruby is recognizing the fact that I'm changing this variable, it's just never saved anywhere.
Ruby 1.9.3, Rails 3.2.6, SQLite3 3.6.20.
tl;dr I need a way to create a class variable, and be able to access it, modify it, and re-store it.
Fixes please? Thanks!
There are a couple solutions here. Essentially, you need to persist that one variable: Postgres provides a key/value store in the database, which would be most ideal, but you're using SQLite so that isn't an option for you. Instead, you'll probably need to use either redis or memcached to persist this information into your database.
Either one allows you to persist values into a schema-less datastore and query them again later. Redis has the advantage of being saved to disk, so if the server craps out on you you can get the value of md5 again when it restarts. Data saved into memcached is never persisted, so if the memcached instance goes away, when it comes back md5 will be 5 once again.
Both redis and memcached enjoy a lot of support in the Ruby community. It will complicate your stack slightly installing one, but I think it's the best solution available to you. That said, if you just can't use either one, you could also write the value of md5 to a temporary file on your server and access it again later. The issue there is that the value then won't be shared among all your server processes.

rails helper to give a upload file a unique name?

Hey guys
I'm now working on a project that require upload a lot of videos, Does rails have this helper can handle this, like the address of youtube video :
www.youtube.com/watch?v=KYUhtPV_Lk4
Thanks
You can generate a random string like this and use it as the file name:
Digest::SHA1.hexdigest(Time.now.to_s) # => 800b262b59296b660a4f73e23580809143ed8846
are you using activerecord to model the files or are they simply flat files somewhere?
if you have a model like UploadedFile << ActiveRecord::Base for each file you can just use the id of the model or if you want a string you can hash it with some string added as salt.
irb(main):021:0> file_id = 1
=> 1
irb(main):022:0> Digest::SHA1.hexdigest('SomeRandomString' + file_id.to_s)
=> "70f5eedc8d4f02fd8f5d4e09ca8925c2f8d6b942"
if you are simply keeping them as flat files on the system, you can hash their path+filename to create a unique string.
irb(main):016:0> Digest::SHA1.hexdigest '/home/bob/somefile.mp4'
=> "204a038eddff90637c529af7003e77d600428271"
and you can always add in a timestamp of the current time and a random number to prevent dupes.
SecureRandom.uuid generates a v4 random UUID (Universally Unique IDentifier)
It doesn't contain meaningful
information such as MAC address, time, etc.
See RFC 4122 for
details of UUID.
SecureRandom::uuid

Resources