I'm trying to read files from in a Model and send the result to a controller. But when I try to display the return value, the only thing I get is the following:
#<Modules:0x007fd559e6cf40>
In my code, I'm just calling Modules.new() and saving the result in a variable:
class WelcomeController < ApplicationController
def index
text = Modules.new "../modules"
puts text
end
end
And my Modules-Model reads a directory, looks for a specific file in each subdirectories and returns the content of that file:
class Modules
include Mongoid::Document
def initialize directory = "./modules"
modules
end
def modules directory = "./modules"
unless Dir[directory].empty?
Dir.glob(directory).each do |folder|
unless Dir["#{directory}/#{folder}"].empty?
Dir.glob(folder).each do |folder|
if File.exist? "module.json"
return open("module.json", "json") do |io| io.read end
end
end
end
end
else
return "Directory empty"
end
end
end
Can someone help me?
Are you trying to look for a module.json file in each of these subdirectories?
Because you will need to pass the full path with the directory. Like:
return File.read("#{folder}/module.json") if File.exist? "#{folder}/module.json"
Related
I have this class. I am using builder gem here.
class ClientsExportXML
def initialize(current_user)
#file = File.new("#{Rails.root}/public/data.xml", 'w')
#clients = Repository::Clients.new(current_user).all
#builder = Builder::XmlMarkup.new(:target=> #file, :indent=> 2)
end
def build
#builder.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8", :company => "Tougg"
#builder.clients do
#clients.each do |c|
#builder.client do
#builder.name(c.name)
#builder.razao_social(c.corporate_name)
#builder.rg(c.rg)
#builder.cpf(c.cpf)
#builder.inscricao_estadual(c.state_registration)
#builder.cnpj(c.cnpj)
#builder.email(c.email)
if c.address
#builder.numero_rua(c.address.street_name)
#builder.bairro(c.address.district)
#builder.complement(c.address.complement)
#builder.cep(c.address.zipcode)
#builder.cidade_estado("#{City.find(c.address.city_id).name}/#{City.find(c.address.city_id).state.symbol}")
end
#builder.telefones do
c.phones.each do |f|
#builder.numero(f.number)
end
end
#builder.notas do
c.notes.each do |n|
#builder.nota do
#builder.nota(n.note)
#builder.adicionada_em(n.created_at.strftime("%d/%m/%y"))
end
end
end
end
end
end
#file.close
end
end
Everything works fine when I execute this in rails console, for example. But, I dont know why, when I try add this in some controller:
def export
....
ClientsExportXML.new(current_user).build
...
end
The file is created at public/data.xml but with no content (empty file).
I am a little confusing about what can may be happening here.
Thanks in advance
Édipo
solved
I change file to an instance variable and close the file at end of method build. I updated the code to reflect this.
Try to add #builder.target! on the last line of the build method. target! method generates XML from the the builder.
Edit:
def export
..
File.open(file_path, "w") do |f|
f.write(ClientsExportXML.new(current_user).build)
end
..
end
Do your export method looks something like this?
I have a module and which have some files under the module
module Man
which has some five files called
module man
module head
def a
end
end
end
module man
module hand
def a
end
end
end
I need to access list of sub-modules that are under the module 'man' and also I need to access the list of methods in each sub-modules.
I tried doing this
array_notification_classes = Dir.entries("app/models/notifications").select {|f| !File.directory? f}
But it returned a list of submodules which is a string.
array_notification_classes = ["head.rb", "hand.rb"]
From now how should I get the list of method names from each sub-module?
Having an array of file names, e.g. array_notification_classes = ["head.rb", "hand.rb"]
array_notification_classes.each do |file_name|
require file_name
include file_name.split(".").first.classify.constantize
end
or into a class:
class Notification
end
array_notification_classes.each do |file_name|
require file_name
Notification.class_eval do
include file_name.split(".").first.classify.constantize
end
end
My array_notification_classes = ["head.rb", "hand.rb"]
array_notification_classes.each do |notification_class|
notification_class = "Notifications::#{notification_class[0..-4].classify}".constantize
notification_class_methods = notification_class.instance_methods
end
This returned all the instance methods in Notifications::Head, notifications::Hand
I'm currently trying to achieve something similar to what is proposed in the chosen answer of this question: Ruby design pattern: How to make an extensible factory class?
class LogFileReader
##subclasses = { }
def self.create type
c = ##subclasses[type]
if c
c.new
else
raise "Bad log file type: #{type}"
end
end
def self.register_reader name
##subclasses[name] = self
end
end
class GitLogFileReader < LogFileReader
def display
puts "I'm a git log file reader!"
end
register_reader :git
end
class BzrLogFileReader < LogFileReader
def display
puts "A bzr log file reader..."
end
register_reader :bzr
end
LogFileReader.create(:git).display
LogFileReader.create(:bzr).display
class SvnLogFileReader < LogFileReader
def display
puts "Subersion reader, at your service."
end
register_reader :svn
end
LogFileReader.create(:svn).display
The unit tests work flawlessly, but when I start the server no class is being registered. May I be missing something about how the static method call is working? When is the register_reader call made by each subclass?
To answer the OP's question about when the classes call register_reader, it happens when the file is loaded. Add this code to an initializer to load the files yourself.
Dir[Rails.root.join('path', 'to', 'log_file_readers', '**', '*.rb').to_s].each { |log_file_reader| require log_file_reader }
The following code is meant to determine which subclass of itself to execute. It cycles through everything in the ObjectSpace to find subclasses and then execute the correct one from there. In rails, this does not work, because classes in the library folder are not in the ObjectSpace. What is a way to search through a specific folder for subclasses?
def execute
ObjectSpace.each_object(Class).select do |klass|
if (klass < self.class)
klass.designations.each do |designation|
if (designation.downcase.capitalize == #action.downcase.capitalize)
command = klass.new(#sumo_params)
command.execute
end
end
end
end
end
OR -- Is there a superior solution to this problem that you would recommend?
I'd say use a module for this. So, this would make you code something like the following:
lib/base_methods.rb
module BaseMethods
def self.included(base)
##classes_including ||= []
##classes_including << base
end
def do_whatever
##classes_including.each do |class|
#....
end
end
end
lib/class_1.rb
class Class1
include BaseMethods
end
I took the easy way out for now (iterating through an array of string values):
def execute
#descendants.each do |descendant|
klass = descendant.downcase.capitalize.constantize
if (klass < self.class)
klass.designations.each do |designation|
if (designation.downcase.capitalize == #action.downcase.capitalize)
command = klass.new(#sumo_params)
command.execute
end
end
end
end
end
I have this Unit Test file:
class WebsiteCheckPageElements < Test::Unit::TestCase
def setup
...
end
def test_achievements_iknow_report_page
...
end
def test_achievements_daily_report_page
...
end
def test_client_side_report_page
...
end
end
I need to write a ruby script that will write the names of the tests to .txt file. Something like
setup
test_achievements_iknow_report_page
test_achievements_daily_report_page
test_client_side_report_page
Thank you in advance for the suggestions.
A more robust way than the other answer:
File.open("test_methods.txt", "w") do |f|
WebsiteCheckPageElements.instance_methods.each do |method|
f << "#{method}\n"
end
end
This will actually use the Ruby runtime and will not fall subject to accidentally matching def in places where it is not defining a method (such as inside a String), it will not match other classes in the file and it will correctly read the inheritance hierarchy.
You could use a simple script that uses regular expressions to print the lines that match def:
match_test_methods.rb
File.open('your_unit_test_file.rb').each_line do |line|
match = line.match(/def (.+)/)
puts match[1] if match
end
Then put the result of the script in a .txt file
ruby match_test_methods.rb > test_methods.txt