Remote_table in spree 0.70.7 controller: #<TypeError: Zip is not a module> - ruby

I'm include gem 'remote_table' in my Gemfile (Rails 3.1.12)
In spree admin i'd create new controller:
class Admin::XlsPriceLoadsController < Admin::BaseController
def upload
source_xls = RemoteTable.new(filename)
source_xls.each do |row|
....
end
end
end
but when this action fired, i'm see the next:
TypeError (Zip is not a module):
app/controllers/admin/xls_price_loads_controller.rb:26:in `upload'
...
when i'm explore the source_xls object, a frozen? property of them is true.
So, can any soul write me, why the parsed object is frozed?
And, if i run this code
source_xls = RemoteTable.new(filename)
source_xls.each do |row|
....
end
from lib/tasks as rake task - all work fine!
Thanks for all advice!

Whereabouts does the filename method/attribute come from? Is that something from spree? What value does it have at the point #upload is called?
Regarding
app/controllers/admin/xls_price_loads_controller.rb:26:inupload'`
What's on line 26?

Related

Getting undefined method `when_visible' for #<Array:0x3db6090> (NoMethodError) in PageObject

I’m getting Getting undefined method `when_visible' for # (NoMethodError) when I used built –in method from PageObject Ruby gem. Here is my code:
class HomePage
include PageObject
links(:search_types, :css => ".search-type")
def select_search_type
search_types_elements.when_visible(timeout=10)
search_types_elements.find { |type| if type.text=='Resort'; type.click; break end }
end
end
Could someone please help? Thanks a lot!
Updated to reflect discussion.
page-object gem handles the plural of its basic accessors. Page-object ultimately generates
search_types_elements = #browser.find_elements(:css, ".search-type")
so you will need to follow it with something like (Updated)
search_types_elements.find { |type|
type.when_visible(timeout=10)
if type.text=='Resort'; type.click; break end
}
You should add something to the page class constructor to wait for the page to completely load. Unfortunately, there isn't a simple way to do this. Much depends on the page specifics. I usually start by waiting for the jquery queue to have zero length. Something like this:
WebDriverWait(self.selenium, 10).until(lambda s: s.execute_script("return jQuery.active == 0"))

Adding a class in a module to Cucumber World

Given I have defined the following modules in my features/support directory
apiworld.rb
module Api
class User
...
end
...
end
and also
webworld.rb
module Web
class User
...
end
...
end
in my env.rb file I have
env.rb
require File.expand_path(File.dirname(__FILE__)+'/webworld')
require File.expand_path(File.dirname(__FILE__)+'/apiworld')
if ENV['USE_API'] == 1
World(Api)
else
World(Web)
end
So if I try to use this construct in a step definition like
Given /^a user is created$/ do
#user = User.new
end
And run cucumber, my ruby interpreter will give me the this output
uninitialized constant User (NameError)
./features/step_definitions/user_steps.rb:17: [...]
How to make this work? Is there a way or am I thinking i the wrong direction. I am pretty new to ruby - so I don't really know what it can do and what it can not do.
You can't use World for this. World is for mixing methods into the self object in each stepdef.
Instead of this:
if ENV['USE_API'] == 1
World(Api)
else
World(Web)
end
Try this:
User = ENV['USE_API'] == 1 ? Api::User : Web::User

Cannot load data file in Sinatra

I created the following parser:
require "./artist"
require "./song"
require "./genre"
require "debugger"
class Parser
attr_accessor :artists, :genres, :song
attr_reader :mp3
REGEX = /(?<artist>.*)\s\-\s(?<song>.*)\s\[(?<genre>.*)\]/
def initialize(directory="data")
debugger
#mp3 = Dir.entries(directory).select {|f| !File.directory? f}
debugger
end
def parse
#mp3.map do |file|
match = REGEX.match(file)
artist = Artist.find_by_name(match[:artist]) || Artist.new.tap {|artist| artist.name = match[:artist]}
song = Song.new
song.name = match[:song]
song.genre = Genre.find_by_name(match[:genre]) || Genre.new.tap {|genre| genre.name = match[:genre]}
#debugger
artist.add_song(song)
end
end
end
a = Parser.new.parse
I tried running it by calling parser.rb in the directory, lib, where it is located. I get the following error messages:
Parser.rb:47:in `open': No such file or directory - data (Errno::ENOENT)
from parser.rb:47:in `entries'
from parser.rb:47:in `initialize'
from parser.rb:68:in `new'
from parser.rb:68:in `<main>'
This is my file structure:
Can anyone please tell me why it cannot recognize my data directory? I have been staring for a while now and cannot figure it out. It was working like 10 mins ago and I cannot remember what I change to get it all messed up.
Appreciate your feedback! Thanks
You should be able to run your example like ruby -I/lib lib/parser.rb from the directory above lib. The -I will set the "include path", such that the ruby interpreter will find the other required ruby files like (lib/)song.rb.

Tracing Ruby Gmail Gem Methods Back To Their Origins

My goal is to find the place where save_attachments_to is called in this gmail gem readme example:
folder = "/where/ever"
gmail.mailbox("Faxes").emails do |email|
if !email.message.attachments.empty?
email.message.save_attachments_to(folder)
end
end
I run a "puts email.message.attachments.methods and a "email.message.attachments.class" in the loop:
Mail::AttachmentsList
guess_encoding
set_mime_type
inspect
Then I run a "puts email.message.methods and a "puts email.message.class" for good measure. The example method call is not in the list.
So I go diving into https://github.com/nu7hatch/gmail/blob/master/lib/gmail/message.rb.
No methods are defined there either, but I notice that mime/message is defined, so I go over there to look at its methods: http://rubydoc.info/gems/mime/0.1/MIME/Message
There is no save_attachments_to method here either.
Where the deuce is this method? The gmail gem does not define attachment methods, so the whole thing must be inherited from somewhere. Where? And where's the call that inherits it?
The reason you can't find it is because it doesn't exist. I'm not sure why. I downloaded the gem and played with it for a while in irb:
1.9.3-p194 :066 > x.message.attachments
=> [#<Mail::Part:70234804200840, Multipart: false, Headers: <Content-Type: application/vnd.ms-excel; name="MVBINGO.xls">, <Content-Transfer-Encoding: base64>, <Content-Disposition: attachment; filename="MVBINGO.xls">, <Content-Description: MVBINGO.xls>>]
1.9.3-p194 :063 > x.message.save_attachments_to(folder)
NoMethodError: undefined method `save_attachments_to' for #<Mail::Message:0x007fc1a3875818>
from /Users/Qsario/.rvm/gems/ruby-1.9.3-p194/gems/mail-2.4.4/lib/mail/message.rb:1289:in `method_missing'
from (irb):63
from /Users/Qsario/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>'
Not very helpful. Ordinarily, you can do something like
puts my_obj.method(:some_method_name).source_location
But when the method in question does not exist, that won't help you very much. EDIT: Now that I look, this exact bug is already on their issue tracker. A few people have posted code to implement the non-existent function, such as this code by a-b:
folder = Dir.pwd # for example
email.message.attachments.each do |f|
File.write(File.join(folder, f.filename), f.body.decoded)
end
Thanks for the sanity check Qsario. :-)
Here is code that works in Ruby 1.9.3 (1.9.3-p194):
gmail = Gmail.connect('username#gmail.com', 'pass')
gmail.inbox.emails.each do |email|
email.message.attachments.each do |f|
File.write(File.join(local_path, f.filename), f.body.decoded)
end
end
Here is code that works in 1.9.2 (1.9.2-p320) and 1.9.3 (1.9.3-p194):
gmail = Gmail.connect('username#gmail.com', 'pass')
gmail.inbox.emails.each do |email|
email.message.attachments.each do |file|
File.open(File.join(local_path, "name-of-file.doc or use file.filename"), "w+b", 0644 ) { |f| f.write file.body.decoded }
end
end

getting active records to display as a plist

I'm trying to get a list of active record results to display as a plist for being consumed by the iphone. I'm using the plist gem v 3.0.
My model is called Post. And I want Post.all (or any array or Posts) to display correctly as a Plist.
I have it working fine for one Post instance:
[http://pastie.org/580902][1]
that is correct, what I would expect. To get that behavior I had to do this:
class Post < ActiveRecord::Base
def to_plist
attributes.to_plist
end
end
However, when I do a Post.all, I can't get it to display what I want. Here is what happens:
http://pastie.org/580909
I get marshalling. I want output more like this:
[http://pastie.org/580914][2]
I suppose I could just iterate the result set and append the plist strings. But seems ugly, I'm sure there is a more elegant way to do this.
I am rusty on Ruby right now, so the elegant way isn't obvious to me. Seems like I should be able to override ActiveRecord and make result-sets that pull back more than one record take the ActiveRecord::Base to_plist and make another to_plist implementation. In rails, this would go in environment.rb, right?
I took the easy way out:
private
# pass in posts resultset from finds
def posts_to_plist(posts)
plist_array = []
posts.each do |post|
plist_array << post.attributes
end
plist_array.to_plist
end
public
# GET /posts
# GET /posts.xml
def index
#posts = Post.all
##posts = [{:a=>"blah"}, {:b=>"blah2"}]
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => posts_to_plist(#posts) }
end
end
I found this page searching for the same answer. I think you have the right approach, though I'm also a newbie (on Rails) and not sure the right way to do it. I added this to application_helper.rb. Seems to work.
require 'plist'
module ApplicationHelper
class ActiveRecord::Base
public
include Plist::Emit
def to_plist
self.attribute_names.inject({}) do |attrs, name|
value = self.read_attribute(name)
if !value.nil?
attrs[name] = value
end
attrs
end
end
end
end
According to the plist project README, you should implement "to_plist_node", as opposed to "to_plist".
You should also mixin Plist::Emit to your ActiveRecord class.

Resources