Rails - Creating temp files in a portable way - ruby-on-rails

My rails application runs on a Ubuntu server machine.
I need to create temporary files in order to "feed" them to a second, independent app (I'll be using rake tasks for this, in case this information is needed)
My question is: what is the best way of creating temporary fields on a rails application?
Since I'm in ubuntu, I could create them on /tmp/whatever, but what would work only in linux.
I'd like my application to be as portable as possible - so it can be installed on Windows machines & mac, if needed.
Any ideas?
Thanks a lot.

tmp/ is definitively the right place to put the files.
The best way I've found of creating files on that folder is using ruby's tempfile library.
The code looks like this:
require 'tempfile'
def foo()
# creates a temporary file in tmp/
Tempfile.open('prefix', Rails.root.join('tmp') ) do |f|
f.print('a temp message')
f.flush
#... do more stuff with f
end
end
I like this solution because:
It generates random file names automatically (you can provide a prefix)
It automatically deletes the files when they are no longer used. For example, if invoked on a rake task, the files are removed when the rake task ends.

Rails apps also have their own tmp/ directory. I guess that one is always available and thus a good candidate to use and keep your application portable.

Related

Storing data inside a ruby gem, where / how to write files?

I've been working on a Ruby parser, that fetches data from different API sources, and compile this data into a clear read-to-use JSON file.
For my use case, i need to store the data i'm initially fetching from the different sources as i don't want to fetch them each time I use the code.
For now i'm writing the JSON i'm receiving from the API sources locally into different JSON files stored in a data folder where my ruby script is. Then i read those files again, parse them and generate my new formatted JSON file that i'm gonna use later in a Rails app.
For that matter i want to create a Gem from this ruby script, which i'm currently working on. Nevertheless i'm not sure to fully understand how and where i should store that data (the one i'm fetching and the one i'm generating).
For now i have tried to simply keep the code as is and simply try to write the file like so:
URI.open("path/to/where/i/wanna/store/file.json", "wb") do |file|
file << URI.open(fetched_data_url).read
end
But wherever i try to write the data i get a :
No such file or directory # rb_sysopen path/to/where/i/wanna/store/file.json
Which in a way does not surprise me that much as i expected it to work in different ways in the context of a Gem. But i'm still missing something here about how to handle this. I'm not sure to fully understand how that all works, especially when you use paths in a gem that will ultimately be used in a rails project.
So several questions here:
Whenever you use a path to write a file inside a Gem, is that path relative to the gem or to the project that will ultimately use that Gem? (and consequently will the file be written inside the project that uses the Gem?)
In that precise use case here, what should i do about it? Where and how do i store my data so that i can use it later? knowing that i need to store it as a JSON file and that for now any attempt of writing a file ends up with an error.
Any input on what i'm misunderstanding here would be much appreciated ! Thanks !
Whenever you use a path to write a file inside a Gem, is that path relative to the gem or to the project that will ultimately use that Gem?
There is nothing special about using file paths whether the code is part of a Gem or not.
path/to/where/i/wanna/store/file.json is a relative path, which means it is looked up relative to the current working directory of the user who started the script. That's nothing special about Gems, that's not even anything to do with Ruby. That is just how file paths work. Relative paths are relative to the current working directory, absolute paths are not.
Where and how do i store my data so that i can use it later?
This depends largely on the Operating System Environment. Different OS Environments have different conventions where to store what kind of files. E.g. your files look like they fit the definition of a cache and Windows has a dedicated folder for caches, as does macOS, as do Linux distributions that follow the Linux Standard Base, as do Desktop Environments that follow the Free Desktop Standards, as does Android, as does iOS, …
For example, the Free Desktop Group has the XDG Base Directory Specification, which defines directories for application state, application data, application cache, and many other things for XDG-compliant environments. Microsoft has similar specifications for Windows. The LSB has something to say as well.

Load multiple configuration files in Rails engine

I'm building a Rails Engine and right now I set all my configuration variables in config/environments/development.rb (within the engine itself, i can also overwrite it from the application later) and can access it from the application with ::Rails.application.config.my_item
This file is getting big and some variables such as config.title = 'Lambda Website' could be placed somewhere else, I was thinking to make a config/settings/my_file.rb and just include it to be able to call it the same way as the development.rb variables but it's more complicated than I expected ... I tried a couple of gems that didn't work at all, maybe because it's an engine. I also tried to require files but it blows up too.
How can I simply split this configuration file easily ? Is there an easy way to include configuration files within an engine ? Both YAML/ERB solution are welcome ...
Thank you guys ;)
Inside your
app/config/initializerz/custom_setting.rb
#custom_setting.rb
YOUR_CONSTANT = WHATEVER
Then feel free to use this constant this anywhere in your app.

Create a global settings file in an open source rails app

I'm trying to create a rails app and have it on github, but I'm running into some trouble separating out personal settings from what I check in to git. Just like how you typically check in a database.yml.example and let people make their own database.yml, I wanted to do that with a bunch of other files (all rb files though), like secret_token and production.rb, but I didn't feel like making the setup process involve copying 15 sample files to files that actually get used.
What I ended up doing was creating a settings.yml.example file in my config dir, and putting all of those settings from the other files in there. then the setup process was just 2 copies (database.yml and settings.yml). Then I added this to the beginning of environment.rb
#allow files to read their private settings from settings.yml using SETTINGS
require 'yaml'
SETTINGS = YAML.load(IO.read(Rails.root.join("config", "settings.yml")))
and when I needed something from the file, I would just say something like
Foo::Application.config.secret_token = SETTINGS["secret_token"]
This worked fine until I tried to run rake test, when it gave me uninitialized constant Rails (NameError) from the Rails.root.join call
My question is is this a good way to accomplish what i'm trying to accomplish? And if so, is there a better place to put the code that loads the settings file? It seems like I can load it before each individual call and just add something like "unless settings is defined" after the load, but that would be annoying to have to do everywhere
Note: For anyone who's curious, the files I would have had to copy were
secret_token.rb
production.rb (for config.action_mailer.default_url_options)
devise.rb (for config.pepper)
I expect more in the future as i start using more libraries (still new to this)
this was answered in a comment, so I'll copy Thomas's answer here to make it more clear.
Both figaro and econfig (by the creator of carrierwave and capybara) are great gems for that purpose. I personally use figaro with it's config/application.yml file that is excluded from version control to great success since a few months on open-source projects.

Why is there Rails.rb files all over the place?

Was digging around my Rails applications and noticed that there are rails.rb files all over the place. In my ruby gems directories like:
...gems\devise-2.0.4\lib\devise\rails.rb
...gems\cucumber-rails-1.3.0\lib\cucumber\rails.rb
...gems\railties-3.2.3\lib\rails.rb
I am assuming that there are executed whenever you issue some command like "rails xxx". So all these extra rails.rb files combine with the original rails.rb file to essentially make one big rails.rb file. Essentially, when we type in "rails xxx" it goes thru all them all?
Just looking for some confirmation PLUS a little more knowledge about this. Thanks.
The best way to understand what these rails.rb files are doing, is to read the source code.
ralties
devise
cucumber-rails
As you can see, in any library the file assumes a different scope. The common behaviour is that the file rails.rb normally contains the code required to initialize the library when loaded from a Rails project.
BTW, this has nothing to do with the script/rails command and there is no "big rails.rb" file.
The files are not generated but are simply source files of these libraries you are using.
In this case they are probably rails-related classes that either extend Rails in some way or modify it or make the library interact with Rails.
Rails is a very common framework in Ruby land so most if not all libraries will have some sort of integration with Rails.
By no means are all of those loaded when you run rails XXX but rather when your application loads these libraries their rails.rb files may be executed to provide some sort of integration with Rails.

What are the performance implications of using require_dependency in Rails 3 applications?

I feel like I understand the difference between require and require_dependency (from How are require, require_dependency and constants reloading related in Rails?).
However, I'm wondering what should happen if I use some of the various methods out there (see http://hemju.com/2010/09/22/rails-3-quicktip-autoload-lib-directory-including-all-subdirectories/ and Best way to load module/class from lib folder in Rails 3?) to get all files loading so we:
don't need to use require_dependency all over the place in the application and
don't have to restart development servers when files in the lib directory change.
It seems like development performance would be slightly impacted, which is not that big of a deal to me. How would performance be impacted in a production environment? Do all of the files generally get loaded only once if you are in production anyway? Is there a better way that I'm not seeing?
If you could include some resources where I could read more about this, they would be greatly appreciated. Some blog posts said that this behavior changed recently with Rails 3 for autoreloading lib/* files and that it was contentious, but I didn't see any links to these discussions. It would be helpful for considering the pros/cons. Thanks!
The code reloader is disabled by default in production. So if you are calling require_dependency at the top of a file it is going to be executed only once.
The Rails 3 change you mentioned is really small. You can usually call Foo and it will be loaded from app/models/foo.rb automatically. Before it could also be loaded from lib/foo.rb. (These directories app/models and lib are called autoload paths.) Rails team decided to remove lib from autoload paths in the 3rd version. You can still put it back. But it is encouraged to leave in lib less frequenttly-changed and project-specific files. If you have something that does not belong to any of the default app subdirectories like app/models or app/controllers you don't have to put it in lib. You can add your own subdirectory. I have app/presenters, for example. There is a discussion on the old issue tracker if you want more info on that.

Resources