Ruby on Rails - Opening a file using Spreadsheet RubyGem - ruby-on-rails-3

I think I'm probably missing something quite simple, as I am new to this gem (and Ruby/Rails in general), but here we go...
I just installed the Spreadsheet gem from RubyGems and used Bundler to install it. Following that, I restarted my local server.
I want to create my database from an Excel file I have, but am struggling to open the file. The code I have is:
require 'spreadsheet'
Spreadsheet.client_encoding = 'UTF-8'
book = Spreadsheet.open('C:\Users\Lev Berlin\Documents\Personal\Projects
\FactsRus\Nutritional Analysis Models\Data for Rails model import.xls')
sheet1 = book.worksheet('Sheet1')
And the error I get after running >rails runner script/load_excel_file.rb (which has the code above) is:
Permission denied - C:\Users...import.xls (Errno::EACCES)
Like I said - I'm probably missing something very simple, but any pointers would be appreciated.

Problem was that the file I was trying to read from was open! N00b mistake, but I eventually figured it out.
Thanks all for looking.

use parseexcel in gem file instead of spreadsheet.
gem 'parseexcel'
write below code in db/seed.rb file place your excel file in project/db/data folder
def seed_cities
workbook = Spreadsheet::ParseExcel.parse("#{Dir.getwd}/db/data/cities.xls")
workbook.worksheet(0).each(1) { |row|
next if row == nil;
col = row.at(0);
next if col == nil;
id = col.to_s('latin1').strip;
next if id == "";
country_id = row.at(1).to_s('latin1').strip;
state_id = row.at(2).to_s('latin1').strip;
name = row.at(3).to_s('latin1').strip;
code = row.at(4).to_s('latin1').strip;
city = City.new(:country_id => country_id, :state_id => state_id, :name => name, :code => code)
unless city.save
city.errors.each { |e| puts "Database Error: ", e }
end
}
end
seed_cities()
this is my cities.xls excel file
id country_id state_id name code
1 7 77 Lahore LHR
2 7 77 Islamabad ISB

Related

Ruby - Not able to read yaml file

Hi all I am retriving data from database and storing it in a File.i am stroing data in yaml format.
require 'mysql2'
require 'yaml'
client = Mysql2::Client.new(:host => "localhost",:username => 'root' , :password => 'root' , :database => 'jgroup')
results = client.query("SELECT * FROM jivegroup")
File.open("D:/j.yml","w") do |file|
results.each do |index|
file.write(index.to_yaml);
end
end
below is my file "j.yml"
---
groupID: 1000
name: T1
description: ""
creationDate: 1209446456903
modificationDate: 1378128624533
---
groupID: 1001
name: T2
description:
creationDate: 1209446473683
modificationDate: 1378181717000
---
but whenver i am trying to load the above file with YAML::load it is giving my only first record. i want to load all records, plz help.
below is my code for reading yml file
YAML::load( File.read('D:/jivegroup.yml') )
{"groupID"=>1000, "name"=>"T1", "description"=>"", "creationDate"=>1209446456903, "modificationDate"=>1378128624533}
If you absolutely want to go with this file design, then use YAML::load_documents to load more than one record at a time.
I would suggest instead using an list in the file. It seems cleaner to me (as what you have is a list of similar records, not a set of unrelated documents).
Hey Finally found answer to my own question on stack overflow itself. i used YAML.load_stream(open("D:/jive_group.yml") instead YAML::load( File.read('D:/jivegroup.yml') )

trying to upload files using a ruby rake task

So I'm using Spree as my shopping cart in Ruby on Rails. Spree is version 1-1-stable, and Ruby is v1.9.3, and Ruby on Rails is v3.2.3.
I have a remote host that has images that I want to download for my Spree cart. This is the code I'm using to pull it. Some of it may not make sense, because I'm trying to do whatever I can to get this to work so it could use a little cleaning.
# Add image to the product
vendor_id = plink_and_pull(item, "VendorID")
image_name = plink_and_pull(item, "ImageName")
# TODO: add if image exists to this unless
unless image_name.nil? || vendor_id.nil? || plink_and_pull(item, "ImageFound").to_i == 0 || File.exists?("/public/prod_images/#{vendor_id}/#{image_name.gsub(' ', '%20')}")
unless Dir.exists? "/public/prod_images/#{vendor_id}"
Dir.mkdir("/public/prod_images/#{vendor_id}", 777)
end
file = File.new("public/prod_images/#{vendor_id}/#{image_name.gsub(' ', '%20')}", 'w+')
file.binmode
open(URI.parse("http://login.xolights.com/vendors/#{vendor_id}/large/#{image_name.gsub(' ', '%20')}")) do |data|
file.write data.read
end
img = Spree::Image.create({:attachment => "public/prod_images/#{vendor_id}/#{image_name}",
:viewable => product}, :without_protection => true)
end
But the error I get says "No such file or directory - /public/prod_images/29" and it references the "Dir.mkdir" line up there. However, I manually created this directory to try to get it to work. In my exception rescue I have the working directory printed out, which is the base directory of my app on my machine. (I am running this on localhost atm.)
I am thinking that maybe I need to do something in my routes.rb file? But I am such a novice at Ruby on Rails routes that I'm not sure where to start... or even if that's the problem here.
I am not that familiar with RubyMine. But rest assured that it's not about routes. It's not Rails-specific. It's Ruby (and OS)-specific because Dir.mkdir is part of standard Ruby library. Just remove the leading / from the path and see whether it works. (So, the actual path will be {your Rails app's root directory}/public/prod_images

Rails 3 + Paperclip: moving current data to another folder

As i'm new to Rails, I made the mistake of using the default path ( /system/:attachment/:id/:style/:filename ) in 4 different models. Now, i would like to move each model to its own folder but without losing old data.
What is the proper way of handling this? Does Paperclip offer an option to automatically migrate data from old folders?
Thanks.
I had a similar dilemma. We were storing all our attachments in a certain path, and then business requirements changed and everything had to be moved and re-organized.
I'm surprised how little info there is on changing paperclip path and moving files. Maybe I'm missing the obvious?
Like Fernando I had to write a rake task. Here's what my code looks like (attachments model is Attachment, and the actual Paperclip::Attachment object is :file )
task :move_attachments_to_institution_folders => :environment do
attachments = Attachment.all
puts "== FOUND #{attachments.size} ATTACHMENTS =="
old_path_interpolation = APP_CONFIG[ 'paperclip_attachment_root' ] + "/:id_partition.:extension"
new_path_interpolation = APP_CONFIG[ 'paperclip_attachment_root' ] + "/:institution/reports/:id_:filename"
attachments.each do |attachment|
# the interpolate method of paperclip takes the symbol variables and evaluates them to proper path segments.
old_file_path = Paperclip::Interpolations.interpolate(old_path_interpolation, attachment.file, attachment.file.default_style) #see paperclip docs
puts "== Current file path: #{old_file_path}"
new_file_path = Paperclip::Interpolations.interpolate(new_path_interpolation, attachment.file, attachment.file.default_style)
if File.exists?(old_file_path)
if !File.exists?(new_file_path) #don't overwrite
FileUtils.mkdir_p(File.dirname(new_file_path)) #create folder if it doesn't exist
FileUtils.cp(old_file_path, new_file_path)
puts "==== File copied (^_^)"
else
puts "==== File already exists in new location."
end
else
puts "==== ! Real File Not Found ! "
end
end
The key thing for me was to have paperclip re-calculate the old path by using its default interpolations. From then it was just a matter of using standard FileUtils to copy the file over. The copy takes care of renaming.
P.S.
I'm on rails 2.3.8 branch, with paperclip -v 2.8.0
I ended up creating a small rake task to do this. Assuming that you have a model called User and your image file is called "image", place the following code in lib/tasks/change_users_folder.rb
desc "Change users folder"
task :change_users_folder => :environment do
#users = User.find :all
#users.each do |user|
unless user.image_file_name.blank?
filename = Rails.root.join('public', 'system', 'images', user.id.to_s, 'original', user.image_file_name)
if File.exists? filename
user.image = File.new filename
user.save
end
end
end
end
Them, run rake change_users_folder and wait.
Note that this won't delete old files. They will be kept at the original place and a copy will be created at the new folder. If everything went well, you can delete them later.
And for my future code, i will make sure i always set :path and :url when using paperclip :)

Change local storage location in refinerycms for uploaded files

I'm using refinerycms 1.0.9 and I'd like to change the default location where dragonfly saves the files.
Here is my dragonfly.rb in config/initializers:
require 'dragonfly'
app = Dragonfly[:app_name]
app.datastore = Dragonfly::DataStorage::FileDataStore.new
app.datastore.configure do |d|
d.root_path = '/Projects/images'
d.server_root = '/Projects'
d.store_meta = false
end
When I save the file I get the following error:
Dragonfly::Shell::CommandFailed (Command failed (identify '/var/folders/5t/mf86p8gx6bz94dzfb88xpvpr0000gn/T/RackMultipart20120328-6943-1vbpa7u') with exit status 127):
UPDATE
I reinstalled imagemagick and that got rid of the error, however it is still saving the files to /system/images. I tried overriding the Image model in refinery and added:
image_accessor :image do
storage_path{ "/Projects/images/#{rand(100)}" }
end
but that didn't work either.
Based on this post from the author it looks like you want to set the storage_path option in your model(s):
storage_path{ "some/path/#{first_name}/#{rand(100)}" } # or whatever you want it to be

Following RoR3 tutorial- tests are inconsistent

I'm following the Ruby on Rails 3 tutorial, chapter 6. Inside my directory spec/models/user_spec.rb, i have a 6 test cases (no need to rly read them):
require 'spec_helper'
describe User do
#pending "add some examples to (or delete) #{__FILE__}"
before(:each) do
#attr = { :name => "Example User", :email => "user#example.com"}
end
it "should creat a new instance given valid attributes" do
User.create!(#attr)
end
.
.
.
it "should reject invalid email addresses" do
addresses = %w[user#foo,com user_at_foo.org example.user#foo.]
addresses.each do |address|
invalid_email_user = User.new(#attr.merge(:email => address))
invalid_email_user.should_not be_valid
end
end
end
In the console, i type $ rspec spec/models/user_spec.rb and it spits out
No DRb server is running. Running in local process instead ...
*
Pending:
User add some examples to (or delete) /Users/matthew/Desktop/rails_projects/sample_app/spec/models/user_spec.rb
# Not Yet Implemented
# ./spec/models/user_spec.rb:4
Finished in 0.00023 seconds
1 example, 0 failures, 1 pending
The last line says i only have 1 example and 1 pending, but i've written 6 tests! This inconsistency boggles my mind! No syntax errors, i'm saving the file, i'm in the right directory, etc.
By far the strangest thing (i'm using Mac OS X and Textmate):
Despite correct code, directory, etc. CMD+S or File-> Save was not saving the files at all. I've been opening the files via command line. Solution is to just close the shell and open a new one.